我想嵌套循环十次,有没有比这更好的方法?

时间:2010-11-07 16:58:02

标签: python perl programming-languages

像这样的东西。我想用10大小的字来强制所有字符

lookup = map(chr, range(32, 127))
for i in lookup:
    for j in lookup:
        for k in lookup:
            for l in lookup:
                for m in lookup:
                    for n in lookup:
                        for o in lookup:
                            for p in lookup:
                                for q in lookup:
                                    for r in lookup:
                                       print(r) # whatever

以下是我的问题

1)还有更好的方法吗?

2)这段代码的一个问题是print(i j k ... r中的任何一个)无法正常工作,你能帮我解决问题吗?如果我给任何字符串它是工作但不是变量

3)我尝试使用perl,即使无法在循环中打印变量,如i,j,.. r

4 个答案:

答案 0 :(得分:15)

虽然使用现有的itertools软件包通常比滚动自己的代码更好,但为了教育价值,最好知道如何自己动手。

显然,嵌套十个循环不是最好的方法。我说“很明显”,因为当你必须复制和粘贴这样的代码时,它会立即引起你的注意。它看起来不是很优雅,是吗?

有几种方法可以更优雅的方式解决这个问题。一种方法是使用递归。要递归地执行此操作,您需要将问题分解为更小的部分。这些是递归规则基本情况。递归规则是您假设您知道如何解决类似但略小的问题版本,然后使用它来解决更大的情况。基本情况是递归的最低点,因为你可以在没有任何进一步递归的情况下找出答案。

递归规则

在我们的例子中,你如何生成一个10个字母的单词?假设您已经知道如何生成9个字母的单词。什么?

for each 9-letter word:
    for each letter 'A' through 'Z':
        yield word + letter

应该清楚的是,对于9个字母的单词,8个字母的单词等,只需对外循环进行少量调整即可。通常,要生成长度 n 的单词,我们将每个长度为 n -1的单词与字母表中的每个字母组合在一起。或者,在Python中:

import string

def all_words(length):
    for word in all_words(length - 1):
        for letter in string.lowercase:
            yield word + letter

让我们尝试运行它。我们从小做起。只用长度为1的所有单词开头怎么样?

>>> list(all_words(1))
  File "<stdin>", line 2, in all_words
  File "<stdin>", line 2, in all_words
  File "<stdin>", line 2, in all_words
  File "<stdin>", line 2, in all_words
RuntimeError: maximum recursion depth exceeded

基本案例

哎呀,发生什么事了?啊对。基本情况。为了生成长度为2的单词,我们递归地生成长度为1的单词。为了生成长度为1的单词,我们生成长度为0的单词。为了生成长度为0的单词,我们生成长度为-1的单词。

等待。什么?长度为-1的单词?这没有意义。在某些时候,我们需要停止递归并简单地返回结果,否则我们将永远递归。这是基本情况。基本情况是您不需要打扰递归的点,因为答案很简单,可以立即弄清楚。

在我们的例子中,当我们被要求生成长度为0的单词时,我们真的不需要做任何繁重的工作。你可以看到长度为0的唯一“单词”是“”,空字符串。它是唯一一个包含0个字符的字符串。所以当length为0时,让我们只返回空字符串:

import string

def all_words(length):
    # Base case
    if length == 0:
        yield ""
    # Recursive rule
    else:
        for word in all_words(length - 1):
            for letter in string.lowercase:
                yield word + letter

好的,让我们再试一次,好吗?

>>> list(all_words(2))
['aa', 'ab', 'ac', 'ad', 'ae', 'af', 'ag', 'ah', 'ai', 'aj', 'ak', 'al', 'am', 'an', 'ao', 'ap', 'aq', 'ar', 'as', 'at', 'au', 'av', 'aw', 'ax', 'ay', 'az',
 'ba', 'bb', 'bc', 'bd', 'be', 'bf', 'bg', 'bh', 'bi', 'bj', 'bk', 'bl', 'bm', 'bn', 'bo', 'bp', 'bq', 'br', 'bs', 'bt', 'bu', 'bv', 'bw', 'bx', 'by', 'bz',
 'ca', 'cb', 'cc', 'cd', 'ce', 'cf', 'cg', 'ch', 'ci', 'cj', 'ck', 'cl', 'cm', 'cn', 'co', 'cp', 'cq', 'cr', 'cs', 'ct', 'cu', 'cv', 'cw', 'cx', 'cy', 'cz',
 'da', 'db', 'dc', 'dd', 'de', 'df', 'dg', 'dh', 'di', 'dj', 'dk', 'dl', 'dm', 'dn', 'do', 'dp', 'dq', 'dr', 'ds', 'dt', 'du', 'dv', 'dw', 'dx', 'dy', 'dz',
 'ea', 'eb', 'ec', 'ed', 'ee', 'ef', 'eg', 'eh', 'ei', 'ej', 'ek', 'el', 'em', 'en', 'eo', 'ep', 'eq', 'er', 'es', 'et', 'eu', 'ev', 'ew', 'ex', 'ey', 'ez',
 'fa', 'fb', 'fc', 'fd', 'fe', 'ff', 'fg', 'fh', 'fi', 'fj', 'fk', 'fl', 'fm', 'fn', 'fo', 'fp', 'fq', 'fr', 'fs', 'ft', 'fu', 'fv', 'fw', 'fx', 'fy', 'fz',
 'ga', 'gb', 'gc', 'gd', 'ge', 'gf', 'gg', 'gh', 'gi', 'gj', 'gk', 'gl', 'gm', 'gn', 'go', 'gp', 'gq', 'gr', 'gs', 'gt', 'gu', 'gv', 'gw', 'gx', 'gy', 'gz',
 'ha', 'hb', 'hc', 'hd', 'he', 'hf', 'hg', 'hh', 'hi', 'hj', 'hk', 'hl', 'hm', 'hn', 'ho', 'hp', 'hq', 'hr', 'hs', 'ht', 'hu', 'hv', 'hw', 'hx', 'hy', 'hz',
 'ia', 'ib', 'ic', 'id', 'ie', 'if', 'ig', 'ih', 'ii', 'ij', 'ik', 'il', 'im', 'in', 'io', 'ip', 'iq', 'ir', 'is', 'it', 'iu', 'iv', 'iw', 'ix', 'iy', 'iz',
 'ja', 'jb', 'jc', 'jd', 'je', 'jf', 'jg', 'jh', 'ji', 'jj', 'jk', 'jl', 'jm', 'jn', 'jo', 'jp', 'jq', 'jr', 'js', 'jt', 'ju', 'jv', 'jw', 'jx', 'jy', 'jz',
 'ka', 'kb', 'kc', 'kd', 'ke', 'kf', 'kg', 'kh', 'ki', 'kj', 'kk', 'kl', 'km', 'kn', 'ko', 'kp', 'kq', 'kr', 'ks', 'kt', 'ku', 'kv', 'kw', 'kx', 'ky', 'kz',
 'la', 'lb', 'lc', 'ld', 'le', 'lf', 'lg', 'lh', 'li', 'lj', 'lk', 'll', 'lm', 'ln', 'lo', 'lp', 'lq', 'lr', 'ls', 'lt', 'lu', 'lv', 'lw', 'lx', 'ly', 'lz',
 'ma', 'mb', 'mc', 'md', 'me', 'mf', 'mg', 'mh', 'mi', 'mj', 'mk', 'ml', 'mm', 'mn', 'mo', 'mp', 'mq', 'mr', 'ms', 'mt', 'mu', 'mv', 'mw', 'mx', 'my', 'mz',
 'na', 'nb', 'nc', 'nd', 'ne', 'nf', 'ng', 'nh', 'ni', 'nj', 'nk', 'nl', 'nm', 'nn', 'no', 'np', 'nq', 'nr', 'ns', 'nt', 'nu', 'nv', 'nw', 'nx', 'ny', 'nz',
 'oa', 'ob', 'oc', 'od', 'oe', 'of', 'og', 'oh', 'oi', 'oj', 'ok', 'ol', 'om', 'on', 'oo', 'op', 'oq', 'or', 'os', 'ot', 'ou', 'ov', 'ow', 'ox', 'oy', 'oz',
 'pa', 'pb', 'pc', 'pd', 'pe', 'pf', 'pg', 'ph', 'pi', 'pj', 'pk', 'pl', 'pm', 'pn', 'po', 'pp', 'pq', 'pr', 'ps', 'pt', 'pu', 'pv', 'pw', 'px', 'py', 'pz',
 'qa', 'qb', 'qc', 'qd', 'qe', 'qf', 'qg', 'qh', 'qi', 'qj', 'qk', 'ql', 'qm', 'qn', 'qo', 'qp', 'qq', 'qr', 'qs', 'qt', 'qu', 'qv', 'qw', 'qx', 'qy', 'qz',
 'ra', 'rb', 'rc', 'rd', 're', 'rf', 'rg', 'rh', 'ri', 'rj', 'rk', 'rl', 'rm', 'rn', 'ro', 'rp', 'rq', 'rr', 'rs', 'rt', 'ru', 'rv', 'rw', 'rx', 'ry', 'rz',
 'sa', 'sb', 'sc', 'sd', 'se', 'sf', 'sg', 'sh', 'si', 'sj', 'sk', 'sl', 'sm', 'sn', 'so', 'sp', 'sq', 'sr', 'ss', 'st', 'su', 'sv', 'sw', 'sx', 'sy', 'sz',
 'ta', 'tb', 'tc', 'td', 'te', 'tf', 'tg', 'th', 'ti', 'tj', 'tk', 'tl', 'tm', 'tn', 'to', 'tp', 'tq', 'tr', 'ts', 'tt', 'tu', 'tv', 'tw', 'tx', 'ty', 'tz',
 'ua', 'ub', 'uc', 'ud', 'ue', 'uf', 'ug', 'uh', 'ui', 'uj', 'uk', 'ul', 'um', 'un', 'uo', 'up', 'uq', 'ur', 'us', 'ut', 'uu', 'uv', 'uw', 'ux', 'uy', 'uz',
 'va', 'vb', 'vc', 'vd', 've', 'vf', 'vg', 'vh', 'vi', 'vj', 'vk', 'vl', 'vm', 'vn', 'vo', 'vp', 'vq', 'vr', 'vs', 'vt', 'vu', 'vv', 'vw', 'vx', 'vy', 'vz',
 'wa', 'wb', 'wc', 'wd', 'we', 'wf', 'wg', 'wh', 'wi', 'wj', 'wk', 'wl', 'wm', 'wn', 'wo', 'wp', 'wq', 'wr', 'ws', 'wt', 'wu', 'wv', 'ww', 'wx', 'wy', 'wz',
 'xa', 'xb', 'xc', 'xd', 'xe', 'xf', 'xg', 'xh', 'xi', 'xj', 'xk', 'xl', 'xm', 'xn', 'xo', 'xp', 'xq', 'xr', 'xs', 'xt', 'xu', 'xv', 'xw', 'xx', 'xy', 'xz',
 'ya', 'yb', 'yc', 'yd', 'ye', 'yf', 'yg', 'yh', 'yi', 'yj', 'yk', 'yl', 'ym', 'yn', 'yo', 'yp', 'yq', 'yr', 'ys', 'yt', 'yu', 'yv', 'yw', 'yx', 'yy', 'yz',
 'za', 'zb', 'zc', 'zd', 'ze', 'zf', 'zg', 'zh', 'zi', 'zj', 'zk', 'zl', 'zm', 'zn', 'zo', 'zp', 'zq', 'zr', 'zs', 'zt', 'zu', 'zv', 'zw', 'zx', 'zy', 'zz']

冷却。

答案 1 :(得分:10)

itertools是你的朋友。

>>> lookup = map(chr, range(32, 127))
>>> import itertools
>>> itertools.permutations(lookup, 10)
<itertools.permutations object at 0x023C8AE0>

请注意,permutations会为您提供每个单词,而combinations会为您提供每组不同的字符。另请注意,有十个字母的单词很多

答案 2 :(得分:1)

我也读过“九十亿上帝的名字”,但我不认为他的世界会在你的节目结束时结束!

更严重的是,您的代码将非常快速和简单。 如果将结果放在数组(或字符串)中,则创建一个指向当前级别的索引,然后对于每个循环,只需增加索引。等级结束后,将其减少为“向后移动”。 这个解决方案不会那么清楚,但它会是动态的 - 即。您可以在运行时选择级别数。

答案 3 :(得分:0)

import itertools

lookup = map(chr, range(32, 127))

for i in itertools.product(lookup, repeat=10):
    print i

但你会喜欢(编辑)96 ^ 10循环所以???

相关问题