在python中,对列表中的字符串进行计数,然后进行过滤和匹配

2024-04-25 08:55:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个单词列表,使用python3计算每个单词组合之间的字母差异(使用clever diff_summing algorithm from this site):

import itertools

def diff_letters(a,b):
    return sum ( a[i] != b[i] for i in range(len(a)) )

w = ['AAHS','AALS','DAHS','XYZA']

for x,y in itertools.combinations(w,2):
    if diff_letters(x,y) == 1:
        print(x,y)

这张照片:

AAHS AALS
AAHS DAHS

我的问题:如何计算记录字符串'DAHS'和'AALS'只有一个伙伴,而'AAHS'有两个伙伴?我将筛选方向组合,其中每个target_string正好有一个near_matching_word,因此我的最终数据(作为JSON)如下所示:

[
 {
   "target_word": "DAHS",
   "near_matching_word": "AAHS"
 },
 {
   "target_word": "AALS",
   "near_matching_word": "AAHS"
 }
]

(注意AAHS不以target_word的形式出现)

我有一个版本使用^{}

import itertools
import functools
import operator

def diff_letters(a,b):
    return sum ( a[i] != b[i] for i in range(len(a)) )

w = ['AAHS','AALS','DAHS','XYZA']

pairs = []
for x,y in itertools.combinations(w,2):
    if diff_letters(x,y) == 1:
        #print(x,y)
        pairs.append((x,y))

full_list = functools.reduce(operator.add, pairs)
for x in full_list:
    if full_list.count(x) == 1:
        print (x)

哪个指纹

AALS
DAHS

但是接下来我必须回到我的大列表pairs,找到near_matching_word。当然,在我的最终版本中,list pairs会更大,并且target_word可以是tuple(x,y)中的第一项或第二项。你知道吗


Tags: inimporttargetfordifflistworditertools
3条回答
import itertools
import functools
import operator


def diff_letters(a, b):
    return sum(a[i] != b[i] for i in range(len(a)))


w = ['AAHS', 'AALS', 'DAHS', 'XYZA']

pairs = []
for x, y in itertools.combinations(w, 2):
    if diff_letters(x, y) == 1:
        pairs.append((x, y))

full_list = functools.reduce(operator.add, pairs)

result = []

for x in set(full_list):
    if full_list.count(x) == 1:
        pair = next((i for i in pairs if x in i))
        match = [i for i in pair if i != x][0]
        result.append({
            "target_word": x,
            "near_matching_word": match
        })

print(result)

输出:

[{'target_word': 'DAHS', 'near_matching_word': 'AAHS'}, {'target_word': 'AALS', 'near_matching_word': 'AAHS'}]

其他答案保留所有配对,即使找到多个。既然不需要它们,那似乎浪费了记忆。这个答案每个字符串最多只能保留一对。你知道吗

import collections
import itertools

def diff_letters(a,b):
    return sum ( a[i] != b[i] for i in range(len(a)) )

w = ['AAHS','AALS','DAHS','XYZA']

# Marker for pairs that have not been found yet.
NOT_FOUND = object()

# Collection of found pairs x => y. Each item is in one of three states:
# - y is NOT_FOUND if x has not been seen yet
# - y is a string if it is the only accepted pair for x
# - y is None if there is more than one accepted pair for x
pairs = collections.defaultdict(lambda: NOT_FOUND)

for x,y in itertools.combinations(w,2):
    if diff_letters(x,y) == 1:
        if pairs[x] is NOT_FOUND:
            pairs[x] = y
        else:
            pairs[x] = None
        if pairs[y] is NOT_FOUND:
            pairs[y] = x
        else:
            pairs[y] = None

# Remove None's and change into normal dict.
pairs = {x: y for x, y in pairs.items() if y}

for x, y in pairs.items():
    print("Target = {}, Only near matching word = {}".format(x, y))

输出:

Target = AALS, Only near matching word = AAHS
Target = DAHS, Only near matching word = AAHS

您可以使用字典而不是成对列表:

pairs = {}
for x, y in itertools.combinations(w, 2):
    if diff_letters(x, y) == 1:
        pairs.setdefault(x, []).append(y)
        pairs.setdefault(y, []).append(x)

result = [{ "target_word": key, "near_matching_word": head, } for key, (head, *tail) in pairs.items() if not tail]

print(result)

输出

[{'target_word': 'AALS', 'near_matching_word': 'AAHS'}, {'target_word': 'DAHS', 'near_matching_word': 'AAHS'}]

pairs字典中,键是target_words,值是near_matching_words。然后使用列表理解过滤掉那些超过1near_matching_word的。你知道吗

相关问题 更多 >

    热门问题