假设我有一个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 :(得分:1)
我想不出任何 one-liner 来解决这个问题,但我相信这很简洁。
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
如果您没有立即看到需要进行异常处理,我们需要捕获因尝试将空列表传递给random.choice()而导致的IndexError。
答案 1 :(得分: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
答案 2 :(得分: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
答案 3 :(得分: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]
请注意,因为您说要保留随机元素,所以我会对列表进行随机播放。迭代完成后,在从列表中删除元素后保留正确的索引。