简体   繁体   English

如何在python中创建一个包含所有可能对的次数相等的列表序列?

[英]how to create a list sequence in python containing all possible pairs an equal number of times?

Given the letters x,y is there a way to write a python function that returns a list sequence containing all possible pairs ( [x,x], [x,y], [y,x], [y,y] ) an equal number of times? 给定字母x,y ,有一种方法可以编写一个python函数,该函数返回一个包含所有可能对( [x,x], [x,y], [y,x], [y,y] )的列表序列。相等次数?

for example can I write a function that takes the input (eg [x,y] ) and the number of times each possible pair should appear (eg 2 ), and then returns, for example, the list sequence: [xxxyyxyyx] ? 例如,我可以编写一个函数来接收输入(例如[x,y] )和每个可能的对出现的次数(例如2 ),然后返回例如列表序列: [xxxyyxyyx]吗?

Preferably I would like the function to generate a "random" sequence so it could also return: 优选地,我希望函数生成一个“随机”序列,以便它也可以返回:

[y x y y x x x y y]

In both cases [x,x] [x,y] [y,x] and [y,y] appear exactly twice. 在两种情况下, [x,x] [x,y] [y,x][y,y]恰好出现两次。

Ideally, I would like to find a solution that also worked with for example 4 letters [x,y,z,w] . 理想情况下,我想找到一种解决方案,该解决方案也适用于例如4个字母[x,y,z,w]

Based on your edits, the following should conduct the tour to which you were referring. 根据您的编辑,以下内容将指导您所参考的浏览。

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)

This outputs 这个输出

['z', 'z', 'z', 'x', 'x', 'y', 'z', 'y', 'y', 'z', 'y', 'x', 'y', 'x', 'z', 'x', 
 'z', 'y', 'x']

With this you can take the most common pairs: 有了这个,您可以选择最常见的对:

>>> 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}

If you care about the pairs only: 如果您只关心配对:

>>> [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')]

If you only care which pairs appear 2 times: 如果您只关心哪些对出现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')]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM