理解并简化这条线
Understanding and simplifying this line
我找到了这个用于查找给定长度的字母表的所有字符串的示例。
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/
>>> alphabet="abcd"
>>> list(itertools.permutations(alphabet,3))
应该负责查找字母表(字长 3)的所有排列
基本上,您使用的是所谓的列表推导式,它本质上是 returns 列表的反向 for 循环。使用这种技术,您可以迭代给定长度的给定字母,将字符串连接在一起。
简而言之,这相当于您的代码,因为我还没有看到其他人为您提供它。我确实推荐使用像 Joran Beasley 写的那样的 itertools,因为它们速度更快,而且它们的声明也更加清晰和简单。
def permute(alphabet):
result = []
for x in alphabet:
for y in alphabet:
result.append(str(x)+str(y))
return result
IDLE 输出为:
>>> 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']
你能弄清楚发生了什么吗?或者我应该写一个解释。 (但请先努力)。
只是一个双列表理解,如果你这样想就简单多了:
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
是 a
、b
、c
、...您使用的各种容器的元素的函数(这部分在'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 [''])]
本质上,它利用了 []
(即空列表)在转换为 bool* 时算作 False
的事实。所以如果列表为空,它将被替换为 ['']
。这是必要的原因是,如果结果是空字符串(或数组),则不会通过 for
循环进行迭代 - 包含空字符串的数组工作正常,因为它有一个元素(一个空字符串)。
这是 bool
的大小写,因为使用了 or
运算符。如果你这样做:
a = var1 or var2
然后,a
将是 var1
- 除非它是算作 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[:]
其中 [:]
是一种复制数组的简单方法。
我找到了这个用于查找给定长度的字母表的所有字符串的示例。
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/
>>> alphabet="abcd"
>>> list(itertools.permutations(alphabet,3))
应该负责查找字母表(字长 3)的所有排列
基本上,您使用的是所谓的列表推导式,它本质上是 returns 列表的反向 for 循环。使用这种技术,您可以迭代给定长度的给定字母,将字符串连接在一起。
简而言之,这相当于您的代码,因为我还没有看到其他人为您提供它。我确实推荐使用像 Joran Beasley 写的那样的 itertools,因为它们速度更快,而且它们的声明也更加清晰和简单。
def permute(alphabet):
result = []
for x in alphabet:
for y in alphabet:
result.append(str(x)+str(y))
return result
IDLE 输出为:
>>> 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']
你能弄清楚发生了什么吗?或者我应该写一个解释。 (但请先努力)。
只是一个双列表理解,如果你这样想就简单多了:
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
是 a
、b
、c
、...您使用的各种容器的元素的函数(这部分在'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 [''])]
本质上,它利用了 []
(即空列表)在转换为 bool* 时算作 False
的事实。所以如果列表为空,它将被替换为 ['']
。这是必要的原因是,如果结果是空字符串(或数组),则不会通过 for
循环进行迭代 - 包含空字符串的数组工作正常,因为它有一个元素(一个空字符串)。
这是 bool
的大小写,因为使用了 or
运算符。如果你这样做:
a = var1 or var2
然后,a
将是 var1
- 除非它是算作 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[:]
其中 [:]
是一种复制数组的简单方法。