简体   繁体   中英

How to randomly merge elements in a single list in Python?

My task is to randomly merge elements of a list 2 at a time.

For example,

list = ["a", "b", "c", "d", "f", "g"]

Then I would like to output something like

a;c
b;f
d;g
etc.

where the combination of the two elements are random.

If the number of elements is odd, I would like to just add the last 3 elements together. For example,

list = ["a", "b", "c", "d", "f", "g", "h"]

would turn into something like

a;c
b;f
d;g;h
etc

So far I have

import random

list = ["a", "b", "c", "d", "f", "g", "h"]
already_seen = []

for i in range(len(list)):
    rand = random.choice(list)
    if rand not in already_seen:
        already_seen.append(rand)
        print(rand + ";" + ?)

You can replace 2 with any other integer (to get triplets etc.)

>>> lst = [2,63,12,13461,13,61,2,12,61,23]
>>> random.shuffle(lst)
>>> [lst[i:i + 2] for i in range(0, len(lst), 2)]
[[13, 2], [61, 23], [2, 12], [13461, 12], [61, 63]]

If your list has an odd number of elements, you will have a singleton list at the end of your list of pairs.

Here is a complete implementation that produces your desired format

from random import shuffle

def combine_elements(my_list):
    shuffle(my_list)
    if (not len(my_list)%2):
        result = [my_list[i]+ ";" + my_list[i+1] for i in range(0,len(my_list)-1,2)]
    else:
        result = [my_list[i]+ ";" + my_list[i+1] for i in range(0,len(my_list)-4,2)]
        result.append((';').join(my_list[-3:]))
    return result

list1 = ["a", "b", "c", "d", "f", "g"]
print(combine_elements(list1))

list2 = ["a", "b", "c", "d", "f", "g", "h"]
print(combine_elements(list2))

# Permanently changes the lists
#print(list1)
#print(list2)

The result, also a list, is printed directly but can also simply be copied into a different variable and manipulated. Note that the calls to combine_elements permanently change your input lists.

import random

list1 = ["a", "b", "c", "d", "f", "g", "h"]

random.shuffle(list1)

shuffled = [list1[i:i+2] for i in range(0, len(list1)-1, 2)]

if len(list1) % 2 == 1:
    shuffled[-1].append(list1[-1])

for e in shuffled:
    print(";".join(map(str, e)))

Output:

f;a
b;c
d;h;g

Similar to @rudolfovic's answer, but having 3 elements at last index if the list length is odd:

lst = ["a", "b", "c", "d", "f", "g", "h"]
random.shuffle(lst)
lsts = [lst[i:i + 2] for i in range(0, len(lst), 2)]
if len(lst) % 2 == 1 and len(lst) > 1: 
    lsts[-2].extend(lsts.pop())
for sublst in lsts:
    print(';'.join(sublst))

Output:

d;b
c;a
g;f;h

This will give you the output you want:

import random

lst = ["a", "b", "c", "d", "f", "g", "h"]
random.shuffle(lst)
for i in range(0,len(lst),2):
    if len(lst)==3:
        print(lst[0]+';'+lst[1]+';'+lst[2])
        break
    else:
        print(lst[0]+';'+lst[1])
        lst.pop(0)
        lst.pop(0)

Example output:

b;f
g;h
a;d;c

This code shuffle the list then print the two first elements like b;f then remove them, if the length of the list is odd, after pop ing the length will be 3 so it will print the 3 elements together like a;d;c

Since everyone seems to be using random.shuffle , here is an answer that doesn't use it

import random

def shuffle(l):
    output = []
    for i in range(len(l)):
        while i not in output:
            n = random.randint(0, len(l)-1)
            if n not in output:
                output.append(n)
                
    return [l[x] for x in output]

l = ["a", "b", "c", "d", "e", "f"]
shuffled = shuffle(l)

output = [shuffled[i:i+2] for i in range(0, len(shuffled), 2)]

print(output)

output

[['d', 'f'], ['e', 'a'], ['b', 'c']]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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