случайным образом выбирать элементы из списка, используя условия из второго списка - PullRequest
0 голосов
/ 11 декабря 2018

Я новичок в Python, так что извините за мой уродливый код ... Мне нужно создать программу, которая позволит мне перегруппировать список, используя условие из другого списка.У меня есть список с именами и список с фамилиями (сортировка важна, потому что каждое имя соответствует eahc фамилии).Идея состоит в том, чтобы создать новый список, выбранный случайным образом из первых имен, при условии, что две фамилии не могут быть рядом (а последний и первый элементы фамилий должны отличаться) ... не уверен, что яочень ясно здесь, надеюсь, вы получите его, посмотрев на мой код.

Вот мой код ниже (он работает при удалении цикла while и повторении его вручную ...).Я уверен, что есть способ сделать это очень просто ...

Любая помощь по этому поводу?

Мел

Мой код:

import random

first_names = ['an','bn','ji','au','jo','ki','ko','bo','mi','li']
last_names = ['A','A','A','R','R','R','C','C','C','C']
results =[]
results_names = []

#picking the first item
tirage = random.choice(list(enumerate(first_names)))
index = tirage[0]
pren = tirage[1]
results.append(pren)
results_names.append(last_names[index])
first_names.remove(pren)
last_names.pop(index)



while len(first_names) > 0 :
    tirage = random.choice(list(enumerate(first_names)))
    index = tirage[0]
    pren = tirage[1]
    if last_names[index] != results_names[len(last_names)-1]:
        results.append(pren)
        results_names.append(last_names[index])
        first_names.remove(pren)
        last_names.pop(index)
        print(results)
        print(results_names)

    if len(resultats_noms) == 10:
        print('liste completed')

    if len(first_names)>9 and last_names[index] == results_names[len(results_names)-1]:
        print('blocked, need to restart',len(results_names),'first names of 10')

1 Ответ

0 голосов
/ 11 декабря 2018

Вы можете перебором, используя random.shuffle () :

import random

def neighbouring(l):
    """Returns True if any 2 elements in l have the same last name."""
    return any( last == l[idx+1][1] for idx,(_,last) in enumerate(l[:-1]) )

first_names = ['an','bn','ji','au','jo','ki','ko','bo','mi','li']
last_names = ['A','A','A','R','R','R','C','C','C','C'] 

# combine first and last name to name-tuples
names = list(zip(first_names,last_names))  
print(names)


tries = 0
len_names = len(names)
# brute force: shuffle until neighbouring(names) == False
while neighbouring(names) and tries < len_names*100: # abort after 100*listlenght tries
    random.shuffle(names)
    tries += 1

print(names)

Вывод:

# before
[('an', 'A'), ('bn', 'A'), ('ji', 'A'), ('au', 'R'), ('jo', 'R'), 
 ('ki', 'R'), ('ko', 'C'), ('bo', 'C'), ('mi', 'C'), ('li', 'C')]

# after
[('bn', 'A'), ('jo', 'R'), ('mi', 'C'), ('au', 'R'), ('ko', 'C'), 
 ('ji', 'A'), ('li', 'C'), ('an', 'A'), ('ki', 'R'), ('bo', 'C')]

Чтобы вернуть основные списки:

first_names, last_names = zip(*names)

print(list(first_names))
print(list(last_names))

Вывод:

['ko', 'bn', 'ki', 'an', 'bo', 'jo', 'mi', 'ji', 'li', 'au']
['C', 'A', 'R', 'A', 'C', 'R', 'C', 'A', 'C', 'R']

Исправлено для бесконечного прогона с именами, которые не могут быть объединены по желанию:

tries = 0
max_tries = len(names) * 100 
while neighbouring(names) and tries < max_tries:
    random.shuffle(names)
    tries += 1

if tries == max_tries:
    print("Check the data - list might still have neighboring dupes after ", 
          tries, " shufflings")
else:
    print("Used ",tries," out of ",max_tries," shufflings")

print(names)
first_names, last_names = zip(*names)

print(list(first_names))
print(list(last_names))
...