2015-06-04 8 views
0

Допустим, у меня есть список Python, который может содержать любую комбинацию членов из следующих двух кортежей:Обеспечит только один член подсписка присутствует в списке Python

legal_letters = ('a', 'b', 'c') 
legal_numbers = (1, 2, 3) 

Так правовые списки комбинации будут включать

combo1 = ['a', 1, '3'] 
combo2 = ['c'] 
combo3 = ['b', 2, 1, 'c'] 

Любая длина, любая комбинация. Вы можете предположить, что в списке комбинаций не будут дублироваться символы. Я хотел бы применить функцию к тем комбинациям, которые их модифицируют (на месте), так что они содержат не более одного члена одного из кортежей - скажем, это числа. «Избранный» член набора чисел следует выбирать произвольно. Мне также все равно, если порядок будет искажен в процессе.

def ensure_at_most_one_number(combo): 
# My first attempts involved set math and a while loop that was 
# pretty gross, I'll spare you guys the details. I'm sure I could get it to work 
# but I figured there might be a one-liner or some fancy itertools out there 
return combo 


# Post transformation 
combo1 = ['a', '1'] 
combo2 = ['c'] 
combo3 = ['c', 'b', 2] # Mangled order, not a problem 

ответ

0

Не самый лучший, но он должен работать

numbers = [] 
for i in legal_numbers: 
    if i in combo: 
    numbers.append(i) 
    combo.remove(i) 
if len(numbers) == 0: 
    return combo 
combo.append(random.choice(numbers)) 
return combo 
0

Может быть это?

def ensure_at_most_one_number(combo): 
    i = len(combo) - 1  # start with the last element 
    found_number = False 

    while i >= 0: 
     try: 
      int(combo[i]) # check element is a number 
      if found_number == True: 
       del combo[i] # remove it if a number already found 
      else: 
       found_number = True 
     except ValueError: 
      pass    # skip element if not a number 
     i -= 1 

    return combo 
0

Отказ от ответственности: Я питон начинающий сам, так что может быть лучше, но это, как я хотел бы сделать это:

import random 

def ensure_at_most_one_number(combo, legal_numbers) : 

    random.shuffle(combo) 
    first_number = True 

    for i in range(len(combo)-1, -1, -1) : 
     if combo[i] in legal_numbers : 
      if first_number : 
       first_number = False 
      else : 
       del combo[i] 

Обратите внимание, что я перетасовать список, так как вы сказали вы хотели сохранить случайный элемент. Итерация выполняется в обратном порядке, чтобы сохранить правильные индексы после удаления элементов из списка.

1

Я не могу придумать ни одного однолинейный, чтобы решить эту проблему, но я считаю, что это достаточно краткий.

def only_one_number(combo): 
     import random 

     try: 
      number = random.choice([x for x in combo if x in legal_numbers]) 
      combo[:] = [x for x in combo if x in legal_letters] 
      combo.append(number) 
     except IndexError: 
      pass 

В случае, если вы немедленно не видит необходимости для обработки исключений, мы должны поймать IndexError, что бы результатом пытается передать пустой список random.choice().