Python!根据与列表中单词的最大距离查找对
Python! Finding pairs depending on maximum distance from words in list
我正在编写一个程序来分析文本文件中的单词。我已经能够解析文本文件中的所有单词,并在执行繁琐的代码后将它们附加到列表中。我现在在这段代码中碰到了一个问题。我现在应该找到不超过索引中最大距离的词对(对于每个词)。
这是我能够获得的输入和字符串列表:
dist_max = int(input('Enter the maximum distance between words ==> '))
list_for_pairs = ['station', 'apple', 'chivalry', 'mansion', 'bear', \
'website', 'vest', 'amazing', 'mansion', 'apple', 'card', \
'station', 'card', 'book', 'same', 'tree', 'honor', \
'leaf', 'trace', 'tractor', 'bucket', 'bread', 'pears', 'book', \
'tractor', 'mouse', 'mansion', 'scratch', 'matter', 'trace']
在这种情况下,最大距离应为 2,例如,对于列表中的单词 'amazing','amazing' 应配对的对将是 'website'、'vest'、'mansion' 和 'apple'。这是因为最大距离为 2,并且列表中的所有单词都在该范围内。
这也是一个示例输出。
配对必须按字母顺序排列,只出现前 5 个和后 5 个,但应该说明总共有多少对。
最后我的代码:
pair_list = []
for i in range(len(list_for_pairs)+1):
range_pos = int(range(0, dist_max)) # This is the range for the maximum distance
# between words in the positive (+) direction
range_neg = int(range(0, dist_max, -1))# This is the range for the maximum distance
# between words in the negative (-) direction
pair_list.append('({} {})'.format(list_for_pairs[i], list_for_pairs[range_pos]))
pair_list.append('({} {})'.format(list_for_pairs[i], list_for_pairs[range_neg]))
不多,但基本上,我想做一个列表来放入所有的对,这将使长度部分更容易,而且我需要确保如果最大距离是我不添加任何东西超出列表范围。感谢任何提示,提前致谢!
使用:
pair_list = []
for i in range(len(list_for_pairs)):
if i > 0:
for j in range(max(0, i - 2)):
pair_list.append('({} {})'.format(list_for_pairs[i], list_for_pairs[j]))
if i < len(list_for_pairs) - 1):
for j in range(i + 1, min(len(list_for_pairs), i + 2)):
pair_list.append('({} {})'.format(list_for_pairs[i], list_for_pairs[range_neg]))
对于每个 i,j 从 1.i - 2 到 i-1 和 2.i + 1 到 i + 2(如果存在)。
您可以有一个嵌套的 for 循环,它是当前索引加上和减去 dist_max 的偏移量。然后确保偏移量不为 0 并且在范围内。
pair_list = []
for i, word in enumerate(list_for_pairs):
for offset in range(-dist_max, dist_max+1):
if offset and 0 <= i + offset < len(list_for_pairs): # Ignore when offset is 0 or would be out of bounds
otherword = list_for_pairs[i + offset]
pair_list.append((word, otherword))
print(pair_list)
这构建了整个对列表。请注意,我使用 set
来消除重复项。
pairs = set()
for i in range(len(list_for_pairs)):
for j in range(-dist_max,dist_max+1):
if not j:
continue
if 0 <= i+j < len(list_for_pairs):
w1, w2 = list_for_pairs[i], list_for_pairs[i+j]
if w1 > w2:
w2,w1 = w1,w2
pairs.add( (w1,w2) )
pairs = sorted(list(pairs))
#print(pairs)
print(len(pairs), "distinct pairs")
for i in range(5):
print( pairs[i][0], pairs[i][1])
print("...")
for i in range(-5,0):
print( pairs[i][0], pairs[i][1])
输出:
C:\tmp>python x.py
Enter the maximum distance between words ==> 2
54 distinct pairs
apples bakery
apples basket
apples bike
apples truck
bakery basket
...
puppy weather
safety vest
scratch trash
track truck
vest whistle
C:\tmp>
您不需要在前后搜索,因为这些对是按字母顺序添加的,与顺序无关。在下面复制的列表中,请注意不需要分析 'weather + challenge'
和 'challenge + weather'
两次。
list_for_pairs = ['weather', 'puppy', 'challenge', 'house', 'whistle', \
'nation', 'vest', 'safety', 'house', 'puppy', 'card', \
'weather', 'card', 'bike', 'equality', 'justice', 'pride', \
'orange', 'track', 'truck', 'basket', 'bakery', 'apples', 'bike', \
'truck', 'horse', 'house', 'scratch', 'matter', 'trash']
dist_max = 2
如果您的列表不包含重复项,则不需要集合来避免重复。您需要做的就是不要添加重复项!一个简单的实现如下所示:
pairs = []
for i in range(dist_max, len(list_for_pairs)):
for j in range(i - dist_max, i):
pair = list_for_pairs[i], list_for_pairs[j]
if pair[1] < pair[0]:
pair = pair[::-1]
pairs.append(pair)
pairs.sort()
这非常适合列表理解,特别是如果您使用 sorted
而不是手动交换对:
pairs = sorted(sorted([list_for_pairs[i], list_for_pairs[j]])
for i in range(dist_max, len(list_for_pairs)) for j in range(i - dist_max, i))
您可以将 [list_for_pairs[i], list_for_pairs[j]]
替换为 list_for_pairs[j:i+1:i-j]
。在我看来,它看起来更漂亮,但我不确定这样做还有什么其他好处:
pairs = sorted(sorted(list_for_pairs[j:i+1:i-j]) for i in range(dist_max, len(list_for_pairs)) for j in range(i - dist_max, i))
由于实际上您的列表 确实 包含重复项,您可以使用 set
来汇总结果。由于集合是无序的,可以在事后对其进行排序:
pairs = sorted(set(sorted(list_for_pairs[j:i+1:i-j])
for i in range(dist_max, len(list_for_pairs)) for j in range(i - dist_max, i)))
作为一个有趣的推论,您还可以在列表排序后使用 itertools.groupby
删除重复项:
pairs = sorted(sorted(list_for_pairs[j:i+1:i-j])
for i in range(dist_max, len(list_for_pairs)) for j in range(i - dist_max, i))
pairs = [k for k, g in groupby(pairs)]
请注意,您也可以将最后一个写成一行,但我认为它太长了,不易读懂。
我正在编写一个程序来分析文本文件中的单词。我已经能够解析文本文件中的所有单词,并在执行繁琐的代码后将它们附加到列表中。我现在在这段代码中碰到了一个问题。我现在应该找到不超过索引中最大距离的词对(对于每个词)。 这是我能够获得的输入和字符串列表:
dist_max = int(input('Enter the maximum distance between words ==> '))
list_for_pairs = ['station', 'apple', 'chivalry', 'mansion', 'bear', \
'website', 'vest', 'amazing', 'mansion', 'apple', 'card', \
'station', 'card', 'book', 'same', 'tree', 'honor', \
'leaf', 'trace', 'tractor', 'bucket', 'bread', 'pears', 'book', \
'tractor', 'mouse', 'mansion', 'scratch', 'matter', 'trace']
在这种情况下,最大距离应为 2,例如,对于列表中的单词 'amazing','amazing' 应配对的对将是 'website'、'vest'、'mansion' 和 'apple'。这是因为最大距离为 2,并且列表中的所有单词都在该范围内。 这也是一个示例输出。
配对必须按字母顺序排列,只出现前 5 个和后 5 个,但应该说明总共有多少对。 最后我的代码:
pair_list = []
for i in range(len(list_for_pairs)+1):
range_pos = int(range(0, dist_max)) # This is the range for the maximum distance
# between words in the positive (+) direction
range_neg = int(range(0, dist_max, -1))# This is the range for the maximum distance
# between words in the negative (-) direction
pair_list.append('({} {})'.format(list_for_pairs[i], list_for_pairs[range_pos]))
pair_list.append('({} {})'.format(list_for_pairs[i], list_for_pairs[range_neg]))
不多,但基本上,我想做一个列表来放入所有的对,这将使长度部分更容易,而且我需要确保如果最大距离是我不添加任何东西超出列表范围。感谢任何提示,提前致谢!
使用:
pair_list = []
for i in range(len(list_for_pairs)):
if i > 0:
for j in range(max(0, i - 2)):
pair_list.append('({} {})'.format(list_for_pairs[i], list_for_pairs[j]))
if i < len(list_for_pairs) - 1):
for j in range(i + 1, min(len(list_for_pairs), i + 2)):
pair_list.append('({} {})'.format(list_for_pairs[i], list_for_pairs[range_neg]))
对于每个 i,j 从 1.i - 2 到 i-1 和 2.i + 1 到 i + 2(如果存在)。
您可以有一个嵌套的 for 循环,它是当前索引加上和减去 dist_max 的偏移量。然后确保偏移量不为 0 并且在范围内。
pair_list = []
for i, word in enumerate(list_for_pairs):
for offset in range(-dist_max, dist_max+1):
if offset and 0 <= i + offset < len(list_for_pairs): # Ignore when offset is 0 or would be out of bounds
otherword = list_for_pairs[i + offset]
pair_list.append((word, otherword))
print(pair_list)
这构建了整个对列表。请注意,我使用 set
来消除重复项。
pairs = set()
for i in range(len(list_for_pairs)):
for j in range(-dist_max,dist_max+1):
if not j:
continue
if 0 <= i+j < len(list_for_pairs):
w1, w2 = list_for_pairs[i], list_for_pairs[i+j]
if w1 > w2:
w2,w1 = w1,w2
pairs.add( (w1,w2) )
pairs = sorted(list(pairs))
#print(pairs)
print(len(pairs), "distinct pairs")
for i in range(5):
print( pairs[i][0], pairs[i][1])
print("...")
for i in range(-5,0):
print( pairs[i][0], pairs[i][1])
输出:
C:\tmp>python x.py
Enter the maximum distance between words ==> 2
54 distinct pairs
apples bakery
apples basket
apples bike
apples truck
bakery basket
...
puppy weather
safety vest
scratch trash
track truck
vest whistle
C:\tmp>
您不需要在前后搜索,因为这些对是按字母顺序添加的,与顺序无关。在下面复制的列表中,请注意不需要分析 'weather + challenge'
和 'challenge + weather'
两次。
list_for_pairs = ['weather', 'puppy', 'challenge', 'house', 'whistle', \
'nation', 'vest', 'safety', 'house', 'puppy', 'card', \
'weather', 'card', 'bike', 'equality', 'justice', 'pride', \
'orange', 'track', 'truck', 'basket', 'bakery', 'apples', 'bike', \
'truck', 'horse', 'house', 'scratch', 'matter', 'trash']
dist_max = 2
如果您的列表不包含重复项,则不需要集合来避免重复。您需要做的就是不要添加重复项!一个简单的实现如下所示:
pairs = []
for i in range(dist_max, len(list_for_pairs)):
for j in range(i - dist_max, i):
pair = list_for_pairs[i], list_for_pairs[j]
if pair[1] < pair[0]:
pair = pair[::-1]
pairs.append(pair)
pairs.sort()
这非常适合列表理解,特别是如果您使用 sorted
而不是手动交换对:
pairs = sorted(sorted([list_for_pairs[i], list_for_pairs[j]])
for i in range(dist_max, len(list_for_pairs)) for j in range(i - dist_max, i))
您可以将 [list_for_pairs[i], list_for_pairs[j]]
替换为 list_for_pairs[j:i+1:i-j]
。在我看来,它看起来更漂亮,但我不确定这样做还有什么其他好处:
pairs = sorted(sorted(list_for_pairs[j:i+1:i-j]) for i in range(dist_max, len(list_for_pairs)) for j in range(i - dist_max, i))
由于实际上您的列表 确实 包含重复项,您可以使用 set
来汇总结果。由于集合是无序的,可以在事后对其进行排序:
pairs = sorted(set(sorted(list_for_pairs[j:i+1:i-j])
for i in range(dist_max, len(list_for_pairs)) for j in range(i - dist_max, i)))
作为一个有趣的推论,您还可以在列表排序后使用 itertools.groupby
删除重复项:
pairs = sorted(sorted(list_for_pairs[j:i+1:i-j])
for i in range(dist_max, len(list_for_pairs)) for j in range(i - dist_max, i))
pairs = [k for k, g in groupby(pairs)]
请注意,您也可以将最后一个写成一行,但我认为它太长了,不易读懂。