Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 列表中字符串之间的字母组合_Python_Performance_Python 2.7_Combinations - Fatal编程技术网

Python 列表中字符串之间的字母组合

Python 列表中字符串之间的字母组合,python,performance,python-2.7,combinations,Python,Performance,Python 2.7,Combinations,我试图比较给定字符串与列表之间的差异。确切地说,我试图将一个给定的单词与我的单词列表进行比较,如果该单词中只有一个字母不同 list = ['fake','bake','sake','rake'] #probably a set 如果给定的单词是take,那么结果将返回false 如果单词是bare,则返回值是bake 我计划这样做的方式是将给定的单词拆分成几个部分,并开始一个循环,将这个单词的每个字母与字典列表(a、b、c)交换。在循环的每次迭代中,我计划检查这个单词是否在我的单词列表中 l

我试图比较给定字符串与列表之间的差异。确切地说,我试图将一个给定的单词与我的单词列表进行比较,如果该单词中只有一个字母不同

list = ['fake','bake','sake','rake'] #probably a set
如果给定的单词是
take
,那么结果将返回
false

如果单词是
bare
,则返回值是
bake

我计划这样做的方式是将给定的单词拆分成几个部分,并开始一个循环,将这个单词的每个字母与字典列表(a、b、c)交换。在循环的每次迭代中,我计划检查这个单词是否在我的单词列表中

list = ['fake','bake','sake','rake'] #probably a set
我只计算了一个4个字母的单词,我需要做大约26^4个循环,以便检查每个字母组合,以匹配我的单词列表

list = ['fake','bake','sake','rake'] #probably a set


有人能告诉我一种检查单词组合的有效方法吗

试着根据每个基本单词逐个字母测试单词。在发现的每个差异上增加一个计数器,并跟踪差异为0或1的单词。这在基本单词的数量上是线性的,比指数方法要好得多

以下是一个参考实现:

def atMostOneDifference(word):
    matching = []
    for baseWord in ['fake','bake','sake','rake']:
        distance = 0
        if len(word) != len(baseWord):
            continue
        # We take the i-th letter from word and baseWord...
        for letter, baseLetter in zip(word, baseWord):
            if letter != baseLetter:
                distance += 1
        if distance <= 1:
            matching.append(baseWord)
    return matching
def atMostOneDifference(word):
匹配=[]
对于['fake'、'bake'、'sake'、'rake']中的基字:
距离=0
如果len(word)!=len(基本字):
持续
#我们从单词和基本单词中提取第i个字母。。。
对于字母,邮政编码的基本字母(单词,基本单词):
如果是字母!=基本字母:
距离+=1

如果距离试着根据每个基本单词逐个字母测试单词。在发现的每个差异上增加一个计数器,并跟踪差异为0或1的单词。这在基本单词的数量上是线性的,比指数方法要好得多

以下是一个参考实现:

def atMostOneDifference(word):
    matching = []
    for baseWord in ['fake','bake','sake','rake']:
        distance = 0
        if len(word) != len(baseWord):
            continue
        # We take the i-th letter from word and baseWord...
        for letter, baseLetter in zip(word, baseWord):
            if letter != baseLetter:
                distance += 1
        if distance <= 1:
            matching.append(baseWord)
    return matching
def atMostOneDifference(word):
匹配=[]
对于['fake'、'bake'、'sake'、'rake']中的基字:
距离=0
如果len(word)!=len(基本字):
持续
#我们从单词和基本单词中提取第i个字母。。。
对于字母,邮政编码的基本字母(单词,基本单词):
如果是字母!=基本字母:
距离+=1
如果距离
这在for循环中使用了相对模糊的子句,如果循环由于
中断退出
,则不会执行该子句,并假设单词长度都相等-测试不相等的长度当然很简单

为您自己的变量使用内置名称(如
list
)是个坏主意-它们不是信息性的,它们会将内置含义隐藏在适当的范围内

这在for循环中使用了相对模糊的子句,如果循环由于
中断退出
,则不会执行该子句,并假设单词长度都相等-测试不相等的长度当然很简单

为自己的变量使用内置名称(如
list
)是个坏主意-它们不是信息性的,它们会将内置含义隐藏在适当的范围内。

可以计算出大量单词之间的距离。使用这个轮子可能比自己发明一个更好

从示例页面:

>>> import jellyfish
>>> jellyfish.levenshtein_distance('jellyfish', 'smellyfish')
2
>>> jellyfish.jaro_distance('jellyfish', 'smellyfish')
0.89629629629629637
>>> jellyfish.damerau_levenshtein_distance('jellyfish', 'jellyfihs')
1
这也适用于你的问题:

import jellyfish
target = 'take'
list = ['teak','fake','bake','sake','rake','sale']
outlist = [x for x in list if jellyfish.levenshtein_distance(x,target) == 1]

print outlist
['fake', 'bake', 'sake', 'rake']
该算法可以计算出单词之间的全部距离。使用这个轮子可能比自己发明一个更好

从示例页面:

>>> import jellyfish
>>> jellyfish.levenshtein_distance('jellyfish', 'smellyfish')
2
>>> jellyfish.jaro_distance('jellyfish', 'smellyfish')
0.89629629629629637
>>> jellyfish.damerau_levenshtein_distance('jellyfish', 'jellyfihs')
1
这也适用于你的问题:

import jellyfish
target = 'take'
list = ['teak','fake','bake','sake','rake','sale']
outlist = [x for x in list if jellyfish.levenshtein_distance(x,target) == 1]

print outlist
['fake', 'bake', 'sake', 'rake']
我自己喜欢切片。 使用返回True/False的函数筛选列表中需要/想要的条件

orig = 'abcdef#ghijklmn'
test = 'abcdef%ghijklmn'
test_bad = 'abcdef%ghijk*mn'

def one_letter_different(s1, s2):
    """returns True if there is only one letter different between s1 and s2.

    Sequentially check each letter of each string till they don't match
    then check to see if the rest of the strings are equal.

    s1, s2 -> str
    """
    for i, c in enumerate(s1):
        if c != s2[i]:
            # test for substituition, deletion and insertion
            return (s1[i + 1:] == s2[i + 1:] or
                    s1[i:] == s2[i + 1:] or
                    s1[i+1:] == s2[i:])
    # s1 equals s2
    return False

print one_letter_different(orig, test)
print one_letter_different(orig, test_bad)

test = 'take'
print [item for item in ['fake','bake','sake','rake']
       if one_letter_different(item, test)]

test = 'bare'
print [item for item in ['fake','bake','sake','rake']
       if one_letter_different(item, test)]
产生:

>>> 
True
False
['fake', 'bake', 'sake', 'rake']
['bake']
>>> 
比较功能也可以定义为:

from operator import ne
from itertools import izip_longest

def one_letter_different(s1, s2):
    """returns True if there is less than two letters different.

    Sequentially compare the letters of each string and sum the differences.

    s1, s2 -> str
    """
    return sum(ne(*thing) for thing in izip_longest(s1, s2, fillvalue = None)) == 1
我自己喜欢切片。 使用返回True/False的函数筛选列表中需要/想要的条件

orig = 'abcdef#ghijklmn'
test = 'abcdef%ghijklmn'
test_bad = 'abcdef%ghijk*mn'

def one_letter_different(s1, s2):
    """returns True if there is only one letter different between s1 and s2.

    Sequentially check each letter of each string till they don't match
    then check to see if the rest of the strings are equal.

    s1, s2 -> str
    """
    for i, c in enumerate(s1):
        if c != s2[i]:
            # test for substituition, deletion and insertion
            return (s1[i + 1:] == s2[i + 1:] or
                    s1[i:] == s2[i + 1:] or
                    s1[i+1:] == s2[i:])
    # s1 equals s2
    return False

print one_letter_different(orig, test)
print one_letter_different(orig, test_bad)

test = 'take'
print [item for item in ['fake','bake','sake','rake']
       if one_letter_different(item, test)]

test = 'bare'
print [item for item in ['fake','bake','sake','rake']
       if one_letter_different(item, test)]
产生:

>>> 
True
False
['fake', 'bake', 'sake', 'rake']
['bake']
>>> 
比较功能也可以定义为:

from operator import ne
from itertools import izip_longest

def one_letter_different(s1, s2):
    """returns True if there is less than two letters different.

    Sequentially compare the letters of each string and sum the differences.

    s1, s2 -> str
    """
    return sum(ne(*thing) for thing in izip_longest(s1, s2, fillvalue = None)) == 1

下面是一个简单的表达式,如果字符串长度不同,则返回不同字母的数量或
False

len(s1) == len(s2) and sum(1 for a, b in zip(s1, s2) if a != b)
就你而言:

target = 'take'
list = ['fake','bake','sake','rake']

def diff(s1, s2): 
    return len(s1) == len(s2) and sum(1 for a, b in zip(s1, s2) if a != b)

print [word for word in list if diff(word, target) == 1]

下面是一个简单的表达式,如果字符串长度不同,则返回不同字母的数量或
False

len(s1) == len(s2) and sum(1 for a, b in zip(s1, s2) if a != b)
就你而言:

target = 'take'
list = ['fake','bake','sake','rake']

def diff(s1, s2): 
    return len(s1) == len(s2) and sum(1 for a, b in zip(s1, s2) if a != b)

print [word for word in list if diff(word, target) == 1]

可能会有帮助:你可以编辑你的候选人名单,使不是所有的单词都匹配。否则,很难测试算法是否有效;^)此外,候选词的字母数是否总是与目标词的字母数相同?如果列表中的某个单词是给定的单词,你想将其包含在结果中吗?@wwii不,它不应该包含自身,但这只是一个
如果
条件,如果单词不是自身,则添加。。。还是有更好的方法that@czi我只是想确定我的答案中的函数是否正确。可能会有帮助:您可以编辑候选列表,以便不是所有单词都匹配。否则,很难测试算法是否有效;^)此外,候选词的字母数是否总是与目标词的字母数相同?如果列表中的某个单词是给定的单词,你想将其包含在结果中吗?@wwii不,它不应该包含自身,但这只是一个
如果
条件,如果单词不是自身,则添加。。。还是有更好的方法that@czi我只是想确定我答案中的函数是否正确。zip检查的目的是什么?介意为你的第二个语句添加注释吗?它同时从两个单词中提取相同(递增)位置的字母。zip检查是为了什么?介意为你的第二个陈述评论一下吗?它同时从两个单词中取相同(递增)位置的字母。-1表示图书馆。这个函数很容易实现,只需一个表达式:
len(s1)=len(s2)和sum(如果a!=b,则zip中a,b的值为1)
对于简单的情况很好,但我一般不同意。您的方法对
snake
bake有什么价值