在python

时间:2019-12-12 02:18:16

标签: python loops for-loop

我正在构建一个小的脚本来执行任务。我在代码的一部分中使用了for循环来给我一个列表,但是,在生成列表时,我需要列表的顺序不正确。为此,我尝试在循环中反转字符串变量“ chat”,以期影响循环变量的值。

但是,我的代码似乎没有执行此操作,因为我在运行时会得到干净的aaaaab等输出,无论我是否注释掉{{1} }。

我要用for循环做些什么吗?还是有其他方法吗?以及如何以另一种方式获得更随机的结果?

此外,我使用列表来确保没有重复,我在最后打印char以确保它已更改,除非它似乎没有循环。

这是代码。

char = char[::-1]

3 个答案:

答案 0 :(得分:1)

不确定您要问什么,但让我尝试解决您遇到的问题:)

import itertools
from random import shuffle

char = "abc"

items = [''.join(x) for x in itertools.product(char, repeat=len(char))]
shuffle(items)

print('\n'.join(items))
print('[+] Printed {} charecters.'.format(len(items)))
python test123.py
bbb
aca
bcb
abb
aab
bcc
acb
cca
abc
ccc
cac
caa
ccb
bca
cbb
bba
aba
aac
baa
bab
bac
cbc
bbc
acc
aaa
cab
cba
[+] Printed 27 charecters.
  

每次运行都会生成相同的“产品列表”,但顺序不同

引擎盖下具有随机输出的超快速“产品”列表生成器!

我花了一些时间来了解工作示例

import itertools
from contextlib import contextmanager
from random import shuffle, sample
from datetime import datetime

char = "abcdefgf"


def generate_product(char):
    items = []
    for i, item in enumerate(itertools.product(char, repeat=len(char))):
        items.append("".join(item))
    shuffle(items)

    return items


def generate(char):
    pools = (char,) * len(char)

    result = ['']
    for i, pool in enumerate(pools):
        # let's shuffle the pool, it will randomize output without extra performance hit
        pool_rnd = sample(pool, k=len(pool))

        result = [x + y for x in result for y in pool_rnd]

    return result


@contextmanager
def timeit(name):
    start = datetime.now()
    print('Started "{}" at {}. Please wait ...'.format(name, start))

    yield

    end = datetime.now()
    print('Finished "{}" at {}! Execution took {}'.format(name, start, end - start))


with timeit('generate_product'):
    items1 = generate_product(char)
    # # print('\n'.join(items1))
    print(' > Contains {} charecters.'.format(len(items1)))

with timeit('generate'):
    items2 = generate(char)
    # print('\n'.join(items2))
    print(' > Contains {} charecters.'.format(len(items2)))

print('Are equal? Sorted comparision result={}'.format(sorted(items1) == sorted(items2)))

比较速度!

#> python test123.py

Started "generate_product" at 2019-12-13 05:35:39.219348. Please wait ...
 > Contains 16777216 charecters.
Finished "generate_product" at 2019-12-13 05:35:39.219348! Execution took 0:00:30.075320
Started "generate" at 2019-12-13 05:36:09.294871. Please wait ...
 > Contains 16777216 charecters.
Finished "generate" at 2019-12-13 05:36:09.294871! Execution took 0:00:02.998755
Are equal? Sorted comparision result=True

0:00:02.9987550:00:30.075320而言!我相信那是胜利!

对该算法再进行一次“压力测试”!

  

在2019-12-13 05:39:01.434788开始“生成”。请耐心等待 ...   包含387420489个字符。   在2019-12-13 05:39:01.434788完成“生成”!执行时间为0:01:20.306413

80秒生成387_420_489个组合的列表!我消耗了25 GB或RAM:D

答案 1 :(得分:-1)

使用itertools.product混乱地创建列表的问题在于itertools.product是一个生成器。该函数接受字符串输入,并一次给您提供字母的每种组合(将字符串像列表一样处理)。有时这很好,因为它可以节省内存。不幸的是,它只是按顺序进行。您可以将函数返回的内容转换为列表,然后使用random.shuffle函数对列表进行加扰并从此处构建加扰的列表

import itertools
import random
char="outlet"
#Here we call the itertools.product function with the reverse of the char variable
myList = itertools.product(char[::-1],repeat=3)#list is sorted here
random.shuffle(myList)#scramble it
myList = [''.join(x) for x in myList]
print(myList)

#myList is no longer sorted

更新:您的代码在每次迭代中都反转字符,因此对于奇数次迭代,您将拥有一个反向字符,而对于偶数,您将拥有一个正向字符。 itertools.product是只运行一次的生成器。无法从循环内部到达它。我不确定您要对生成器的输出进行什么操作,或者与char的关系如何,但是我认为这并不是您似乎正在做的事情的正确工具。另外,如果要确保列表中每个实例只有一个,并且顺序无关紧要,则set()是适合您的类型,而不是list()。 Set确保没有重复,因此您不必手动检查。但是它没有顺序,所以您不能指望顺序保持不变。

答案 2 :(得分:-2)

您正在循环内更改char,该循环遍历product(char, repeat=3)

尽管char每次都会更改(您可以通过打印对其进行检查),但这不会影响正在循环的数据。如果您考虑一下,那是有道理的:您期望会发生什么?

该循环仅完成对原始产品的迭代,并且每个值将按顺序显示,而将char反转则无济于事。

如果您尝试显示原始字符串中所有三个字符的字符组合,但是以随机顺序显示,则可以:

import random
import itertools

chars = 'abc'

result = list(itertools.product(chars, repeat=3))
random.shuffle(result)

for x in result:
    print(''.join(x))