我正在构建一个小的脚本来执行任务。我在代码的一部分中使用了for
循环来给我一个列表,但是,在生成列表时,我需要列表的顺序不正确。为此,我尝试在循环中反转字符串变量“ chat”,以期影响循环变量的值。
但是,我的代码似乎没有执行此操作,因为我在运行时会得到干净的aaa
,aab
等输出,无论我是否注释掉{{1} }。
我要用for循环做些什么吗?还是有其他方法吗?以及如何以另一种方式获得更随机的结果?
此外,我使用列表来确保没有重复,我在最后打印char以确保它已更改,除非它似乎没有循环。
这是代码。
char = char[::-1]
答案 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.998755
对0: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))