理解并简化这一行

时间:2015-03-06 00:52:20

标签: python string alphabet

我发现这个例子用于查找给定长度的字母表的所有字符串。

for i in range(length):
    result = [str(x)+str(y) for x in alphabet for y in result or ['']]

我试图理解它是如何工作的,如果这是用for循环实现的,它看起来怎么样 - 我所有的简化它的尝试都变得非常混乱并且无限循环崩溃......而这一切都是有效的时间。


示例:

def allstrings(alphabet, length):
    """Find the list of all strings of 'alphabet' of length 'length'"""

    alphabet = list(alphabet)

    result = []

    for i in range(length):
        result = [str(x)+str(y) for x in alphabet for y in result or ['']]

    return result

# will return ['aa', 'ab', 'ba', 'bb']
print(allstrings({'a', 'b'}, 2)))

# will return ['000', '001', '010', '011', '100', '101', '110', '111']
print(allstrings({'0', '1'}, 4)))

代码修改自:http://code.activestate.com/recipes/425303-generating-all-strings-of-some-length-of-a-given-a/

4 个答案:

答案 0 :(得分:5)

>>> alphabet="abcd"
>>> list(itertools.permutations(alphabet,3))

应该注意找到字母表的所有排列(字长3)

答案 1 :(得分:1)

基本上,您正在使用所谓的列表推导,它本质上是一个返回列表的向后循环。使用这种技术,您可以迭代给定长度的给定字母,将字符串连接在一起。

答案 2 :(得分:1)

简而言之,这相当于您的代码,因为我没有看到其他人提供给您。我建议使用像Joran Beasley写的itertools,因为它们更快,而且它们也能做出清晰简单的陈述。

def permute(alphabet):
    result = []
    for x in alphabet:
        for y in alphabet:
            result.append(str(x)+str(y))
    return result

将IDLE中的ouptut作为:

>>> alphabet = ["a", "b", "c"]
>>> r = permute(alphabet)
>>> r
['aa', 'ab', 'ac', 'ba', 'bb', 'bc', 'ca', 'cb', 'cc']

然而,这种方法使得定义所需长度变得更加困难。要达到这个效果,您必须执行以下操作:

def permute(original, permutated):
    result = []
    for x in alphabet:
        for y in permutated or [""]:
            result.append(str(x)+str(y))
    return result

def helper(alphabet, length):
    res = []
    for i in range(length):
        res = permute(alphabet, res)
    return res

现在的输出如下:

>>> h = helper(alphabet, 2)
>>> h
['aa', 'ab', 'ac', 'ba', 'bb', 'bc', 'ca', 'cb', 'cc']
>>> h = helper(alphabet, 3)
>>> h
['aaa', 'aab', 'aac', 'aba', 'abb', 'abc', 'aca', 'acb', 'acc', 'baa', 'bab', 'bac', 'bba', 'bbb', 'bbc', 'bca', 'bcb', 'bcc', 'caa', 'cab', 'cac', 'cba', 'cbb', 'cbc', 'cca', 'ccb', 'ccc']

你能弄清楚发生了什么吗?或者我应该写一个解释。 (但请先努力)。

答案 3 :(得分:0)

它只是一个双重列表理解,如果您这样想的话,它会简单得多:

print [a for a in "abc"] # ['a', 'b', 'c']

如果你在那里做两件for ... in ...件事,它就像一个嵌套的循环;

result = [XXX for a in as for b in bs for c in cs...]

其中XXX是您使用的各种容器的abc,...元素的函数(此部分位于&#后面) 39; in' s)转换为:

result = []
for a in as:
  for b in bs:
    for c in cs:
      ...#however much nesting you want
      result.append(XXX)

您可以通过交换订单来看到这一点:

print [a+b for a in "ab" for b in "xy"] # ax ay bx by
print [a+b for b in "xy" for a in "ab"] # ax bx ay by

现在举个实例:

for i in range(length):
  result = [str(x)+str(y) for x in alphabet for y in result or ['']]


this just follows the same rules as above, but there is one extra little hitch; the `result or ['']` part. It is possible to have `if ... else ...` style constructs in list comprehensions, though you'll probably want to avoid those for now. That is *not* what's happening here though, the code is a little clearer if you change it to this:

for i in range(length):
  result = [str(x)+str(y) for x in alphabet for y in (result or [''])]

基本上,它在利用[](即空列表)作为False投射到布尔*时利用了这一事实。因此,如果列表为空,则将替换为['']。这是必要的原因是,如果result是一个空字符串(或数组),则不会发生for循环的迭代 - 包含空字符串的数组工作得很好,因为它有一个元素(一个空字符串)。

bool是一种情况,因为使用了or运算符。如果您这样做:

a = var1 or var2

然后,avar1 - 除非它是计为False的对象之一;

print False or "other" # other
print None or "other" # other
print True or "other" # True
print "" or "other" # other
print " " or "other" # ' '
print 0 or "other" # other
print 1 or "other" # 1
print 134513456 or "other" # 134513456
print [] or "other" # other
print [0] or "other" # [0]
...

我相信你能得到这张照片。

您所拥有的代码的另一个可能令人困惑的方面是它设置变量result,同时在列表推导中使用相同的变量。这没关系,因为在列表理解完成之前,变量不会被设置。

所以要使用普通循环将其转换为某些东西:

for i in range(length):
  result = [str(x)+str(y) for x in alphabet for y in result or ['']]


result = [""]
for i in range(length):
  temporary_result = []
  for original_sequence in result:
    for new_letter in alphabet:
      temporary_result.append(original_sequence + new_letter)
  result = temporary_result[:]

其中[:]是复制数组的简单方法。