簡體   English   中英

Python! 根據與列表中單詞的最大距離查找對

[英]Python! Finding pairs depending on maximum distance from words in list

我正在編寫一個分析文本文件中單詞的程序。 在經過艱苦的代碼之后,我已經能夠將文本文件中的所有單詞和 append 解析到一個列表中。 我現在在這段代碼中遇到了一個問題。 我現在應該找到不超過索引中最大距離的單詞對(對於每個單詞)。 這是我能夠獲得的輸入和字符串列表:

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”和'蘋果'。 這是因為最大距離為 2,並且列表中的所有單詞都在該范圍內。 這也是一個示例 output。

這些對必須按字母順序排列,只有第一個和最后 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])

Output:

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:ij] 在我看來,它看起來更漂亮,但我不確定這樣做還有什么其他好處:

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)]

請注意,您也可以將最后一個寫成單行,但我認為它太長而不易閱讀。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM