如何在 python 中创建包含所有可能对的次数相等的列表序列?
how to create a list sequence in python containing all possible pairs an equal number of times?
给定字母 x,y
是否有一种方法可以编写一个 python 函数,其中 return 是一个包含所有可能对 ([x,x], [x,y], [y,x], [y,y]
) 的列表序列次?
例如,我可以编写一个函数来获取输入(例如 [x,y]
)和每对可能出现的次数(例如 2
),然后 return s,例如列表序列:
[x x x y y x y y x]
?
最好我希望函数生成一个 "random" 序列,这样它也可以 return:
[y x y y x x x y y]
在这两种情况下,[x,x] [x,y] [y,x]
和 [y,y]
恰好出现了两次。
理想情况下,我想找到一个也适用于例如 4 个字母的解决方案 [x,y,z,w]
。
根据您的编辑,以下人员应该会进行您所指的游览。
import random
import itertools
def generate_sequence(alphabet, num_repeats):
# generate the permutations of the list of size 2
# repeated `num_repeats` times
perms = [(letter1, letter2) for letter1, letter2 in itertools.product(alphabet, alphabet) for i in xrange(num_repeats)]
# save the original length of `perm` for later
perm_len = len(perms)
# randomly choose a starting point and add it to our result
curr_s, curr_e = random.choice(perms)
result = [curr_s, curr_e]
# remove the starting point from the list... on to the next one
perms.remove((curr_s, curr_e))
# while we still have pairs in `perms`...
while len(perms):
# get all possible next pairs if the end of the current pair
# equals the beginning of the next pair
next_vals = [(s,e) for s,e in perms if s == curr_e]
# if there aren't anymore, we may have exhausted the pairs that
# start with `curr_e`, in which case choose a new random pair
if len(next_vals) != 0:
next_s, next_e = random.choice(next_vals)
else:
next_s, next_e = random.choice(perms)
# remove the next pair from `perm` and append it to the `result`
perms.remove((next_s, next_e))
result.append(next_e)
# set the current pair to the next pair and continue iterating...
curr_s, curr_e = next_s, next_e
return result
alphabet = ('x', 'y', 'z')
num_repeats = 2
print generate_sequence(alphabet, num_repeats)
这输出
['z', 'z', 'z', 'x', 'x', 'y', 'z', 'y', 'y', 'z', 'y', 'x', 'y', 'x', 'z', 'x',
'z', 'y', 'x']
有了这个你可以得到最常见的对:
>>> from collections import Counter
>>> dict(Counter(zip(a, a[1:])).most_common())
{('z', 'z'): 2, ('z', 'y'): 2, ('x', 'y'): 2, ('z', 'x'): 2, ('y', 'y'): 2, ('x', 'x'): 2, ('y', 'x'): 2, ('x', 'z'): 2, ('y', 'z'): 2}
如果您只关心对:
>>> [t[0] for t in Counter(zip(a, a[1:])).most_common()]
[('z', 'z'), ('z', 'y'), ('x', 'y'), ('z', 'x'), ('x', 'x'), ('y', 'x'), ('x', 'z'), ('y', 'y'), ('y', 'z')]
如果你只关心哪对出现2次:
>>> [pair for pair, count in Counter(zip(a, a[1:])).items() if count == 2]
[('z', 'z'), ('z', 'y'), ('x', 'y'), ('z', 'x'), ('x', 'x'), ('y', 'x'), ('x', 'z'), ('y', 'y'), ('y', 'z')]
给定字母 x,y
是否有一种方法可以编写一个 python 函数,其中 return 是一个包含所有可能对 ([x,x], [x,y], [y,x], [y,y]
) 的列表序列次?
例如,我可以编写一个函数来获取输入(例如 [x,y]
)和每对可能出现的次数(例如 2
),然后 return s,例如列表序列:
[x x x y y x y y x]
?
最好我希望函数生成一个 "random" 序列,这样它也可以 return:
[y x y y x x x y y]
在这两种情况下,[x,x] [x,y] [y,x]
和 [y,y]
恰好出现了两次。
理想情况下,我想找到一个也适用于例如 4 个字母的解决方案 [x,y,z,w]
。
根据您的编辑,以下人员应该会进行您所指的游览。
import random
import itertools
def generate_sequence(alphabet, num_repeats):
# generate the permutations of the list of size 2
# repeated `num_repeats` times
perms = [(letter1, letter2) for letter1, letter2 in itertools.product(alphabet, alphabet) for i in xrange(num_repeats)]
# save the original length of `perm` for later
perm_len = len(perms)
# randomly choose a starting point and add it to our result
curr_s, curr_e = random.choice(perms)
result = [curr_s, curr_e]
# remove the starting point from the list... on to the next one
perms.remove((curr_s, curr_e))
# while we still have pairs in `perms`...
while len(perms):
# get all possible next pairs if the end of the current pair
# equals the beginning of the next pair
next_vals = [(s,e) for s,e in perms if s == curr_e]
# if there aren't anymore, we may have exhausted the pairs that
# start with `curr_e`, in which case choose a new random pair
if len(next_vals) != 0:
next_s, next_e = random.choice(next_vals)
else:
next_s, next_e = random.choice(perms)
# remove the next pair from `perm` and append it to the `result`
perms.remove((next_s, next_e))
result.append(next_e)
# set the current pair to the next pair and continue iterating...
curr_s, curr_e = next_s, next_e
return result
alphabet = ('x', 'y', 'z')
num_repeats = 2
print generate_sequence(alphabet, num_repeats)
这输出
['z', 'z', 'z', 'x', 'x', 'y', 'z', 'y', 'y', 'z', 'y', 'x', 'y', 'x', 'z', 'x',
'z', 'y', 'x']
有了这个你可以得到最常见的对:
>>> from collections import Counter
>>> dict(Counter(zip(a, a[1:])).most_common())
{('z', 'z'): 2, ('z', 'y'): 2, ('x', 'y'): 2, ('z', 'x'): 2, ('y', 'y'): 2, ('x', 'x'): 2, ('y', 'x'): 2, ('x', 'z'): 2, ('y', 'z'): 2}
如果您只关心对:
>>> [t[0] for t in Counter(zip(a, a[1:])).most_common()]
[('z', 'z'), ('z', 'y'), ('x', 'y'), ('z', 'x'), ('x', 'x'), ('y', 'x'), ('x', 'z'), ('y', 'y'), ('y', 'z')]
如果你只关心哪对出现2次:
>>> [pair for pair, count in Counter(zip(a, a[1:])).items() if count == 2]
[('z', 'z'), ('z', 'y'), ('x', 'y'), ('z', 'x'), ('x', 'x'), ('y', 'x'), ('x', 'z'), ('y', 'y'), ('y', 'z')]