我正在寻找的是最佳方式,'如果此列表太短,将其延长为9个元素并添加'选择4','选择5'等作为附加元素。另外,用'Choice x'替换任何'None'元素。也可以替换“”和0。
示例转换将是
['a','b',None,'c']
到
['a','b','Choice 3','c','Choice 5','Choice 6','Choice 7','Choice 8','Choice 9']
我的初始代码滥用了try / except,并且有一个我没注意到的一个错误;感谢joeforker和所有指出的人。根据评论,我尝试了两个同样测试良好的简短解决方案:
def extendChoices(cList):
for i in range(0,9):
try:
if cList[i] is None:
cList[i] = "Choice %d"%(i+1)
except IndexError:
cList.append("Choice %d"%(i+1)
和
def extendChoices(cList):
# Fill in any blank entries
for i, v in enumerate(cList):
cList[i] = v or "Choice %s" % (i+1)
# Extend the list to 9 choices
for j in range(len(cList)+1, 10):
cList.append("Choice %s" % (j))
我认为#2赢得更多pythonic,所以它是我将使用的那个。它易于理解和使用常见的结构。拆分步骤是合乎逻辑的,可以使人们更容易理解。
答案 0 :(得分:10)
与zip
不同,Python的map
会自动使用None
扩展较短的序列。
map(lambda a, b: b if a is None else a,
choicesTxt,
['Choice %i' % n for n in range(1, 10)])
您可以将lambda简化为
map(lambda a, b: a or b,
choicesTxt,
['Choice %i' % n for n in range(1, 10)])
如果可以在choicesTxt
中处理与None
相同的其他虚假对象。
答案 1 :(得分:7)
我最初的反应是将列表扩展名和“填空”填入单独的部分,如下所示:
for i, v in enumerate(my_list):
my_list[i] = v or "Choice %s" % (i+1)
for j in range(len(my_list)+1, 10):
my_list.append("Choice %s" % (j))
# maybe this is nicer for the extension?
while len(my_list) < 10:
my_list.append("Choice %s" % (len(my_list)+1))
如果您坚持使用try...except
方法,请抓住Douglas显示的特定异常。否则,您将抓住所有内容:KeyboardInterrupts
,RuntimeErrors
,SyntaxErrors
,....你不想这样做。
编辑:修复了1个索引列表错误 - 感谢DNS!
编辑:添加了替代列表扩展
答案 2 :(得分:3)
您可以使用map(字典)代替list:
choices_map = {1:'Choice 1', 2:'Choice 2', 3:'Choice 12'}
for key in xrange(1, 10):
choices_map.setdefault(key, 'Choice %d'%key)
然后您的地图填满了您的数据 如果你想要一个列表,你可以这样做:
choices = choices_map.values()
choices.sort() #if you want your list to be sorted
#In Python 2.5 and newer you can do:
choices = [choices_map[k] for k in sorted(choices_map)]
答案 3 :(得分:3)
我想我会做一些非常类似的事情,但有一些整洁的事情:
for i in range(0,10):
try:
if choicesTxt[i] is None:
choicesTxt[i] = "Choice %d"%i
except IndexError:
choicesTxt.append("Choice %d"%i)
其中唯一重要的两个是仅捕获IndexError
而不是任何异常,并从0开始索引。
如果choicesTxt
为空,那么原始的唯一真正问题是,当添加的选项将被关闭时。
答案 4 :(得分:2)
我认为你应该把调整数组大小作为一个单独的步骤。为此,如果数组太短,请调用choicesTxt=choicesTxt+[None]*(10-len(choicesTxt))
。
可以使用列表推导来完成None
选择重新分配。
答案 5 :(得分:2)
对我来说,最简单,最pythonic是:
repl = lambda i: "Choice %d" % (i + 1) # DRY
print ([(x or repl(i)) for i, x in enumerate(aList)]
+ [repl(i) for i in xrange(len(aList), 9)])
答案 6 :(得分:1)
我发现当列表推导变长时,最好只使用标准for循环。 几乎和其他人一样,但无论如何:
>>> in_list = ["a","b",None,"c"]
>>> full_list = in_list + ([None] * (10 - len(in_list)))
>>> for idx, value in enumerate(full_list):
... if value == None:
... full_list[idx] = 'Choice %d' % (idx + 1)
...
>>> full_list
['a', 'b', 'Choice 3', 'c', 'Choice 5', 'Choice 6', 'Choice 7', 'Choice 8', 'Choice 9', 'Choice 10']
答案 7 :(得分:1)
好一行:
[a or 'Choice %d' % i for a,i in map(None,["a","b",None,"c"],range(10))]
虽然那会用“Choice n”替换任何评价为False的东西(例如None,',0等)。如果yuo不想要,最好用函数替换"a or 'Choice %d' % i"
。
关键是可以使用参数为None的map
将列表扩展到所需位置的None所需的长度。
更整洁(更pythonic)的版本将是:
def extend_choices(lst,length):
def replace_empty(value,index):
if value is None:
return 'Choice %d' % index
return value
return [replace_empty(value,index) for value,index in map(None,lst,range(length))]
答案 8 :(得分:1)
def choice_n(index):
return "Choice %d" % (index + 1)
def add_choices(lst, length, default=choice_n):
"""
>>> add_choices(['a', 'b', None, 'c'], 9)
['a', 'b', 'Choice 3', 'c', 'Choice 5', 'Choice 6', 'Choice 7', 'Choice 8', 'Choice 9']
"""
for i, v in enumerate(lst):
if v is None:
lst[i] = default(i)
for i in range(len(lst), length):
lst.append(default(i))
return lst
if __name__ == "__main__":
import doctest
doctest.testmod()
答案 9 :(得分:1)
你可以通过列表理解更简单:
extendedChoices = choices + ([None] * (10 - len(choices)))
newChoices = ["Choice %d" % (i+1) if x is None else x
for i, x in enumerate(extendedChoices)]
这会将None
追加到您的选择列表中,直到它至少包含10个项目,通过结果进行枚举,如果缺少第X个元素,则插入“Choice X”。
答案 10 :(得分:1)
choices[:] = ([{False: x, True: "Choice %d" % (i + 1)}[x is None] for i, x in enumerate(choices)] +
["Choice %d" % (i + 1) for i in xrange(len(choices), 9)])
答案 11 :(得分:1)
我愿意
for i, c in enumerate(choices):
if c is None:
choices[i] = 'Choice X'
choices += ['Choice %d' % (i+1) for i in range(len(choices), 10)]
只替换实际的None
值(不是任何评估为false的值),并在一个单独的步骤中扩展列表,我认为更清楚。
答案 12 :(得分:1)
我有点不清楚你为什么使用射程(1,10);因为你正在使用choicesTxt [i],所以最终会跳过列表中第一个元素的None检查。
此外,如果您正在创建新列表,显然有更简单的方法可以执行此操作,但您要求专门添加到现有列表。
我认为这不是更清洁或更快,但你想到的是一个不同的想法。
for i, v in enumerate(choicesTxt):
choicesTxt[i] = v or "Choice " + str(i + 1)
choicesTxt.extend([ "Choice " + str(i) for i in range(len(choicesTxt) + 1, 10) ])
答案 13 :(得分:1)
如果你不介意用“Choice%d”替换任何评价为False的东西,那么result
适用于Python 2.4。
如果您介意并使用Python 2.5及更高版本,那么请使用具有三元result2_5_plus
功能的if
。
如果您不喜欢或不能使用三元if,那么请利用True == 1
和False == 0
这一事实,使用x is None
的结果来索引列表。
x = ["Blue", None, 0, "", "No, Yelloooow!"]
y = [None]*9
result = [(t or "Choice %d" % (i+1))\
for i, t in enumerate(x + y[len(x):])]
result2_5_plus = [(t if t is not None else "Choice %d" % (i+1))\
for i, t in enumerate(x + y[len(x):])]
result_no_ternary_if = [[t, "Choice %d" % (i+1)][t is None]\
for i, t in enumerate(x + y[len(x):])]
['Blue', 'Choice 2', 'Choice 3', 'Choice 4', 'No, Yelloooow!', 'Choice 6', 'Choice 7', 'Choice 8', 'Choice 9']
['Blue', 'Choice 2', 0, '', 'No, Yelloooow!', 'Choice 6', 'Choice 7', 'Choice 8', 'Choice 9']
答案 14 :(得分:1)
怎么样(似乎是一个字典 - 不是列表 - 当它不完整时)
a = {1:'a', 2:None, 5:'e'} #test data
[a[x] if x in a and a[x] is not None else 'Choice %d'%x for x in xrange(1,10)]
再次编辑:如果它真的是一个列表(不是字典):
b=['a',None,'b']
[b[x] if len(b)>x and b[x] is not None else 'Choice %d'%x for x in xrange(10)]
我认为需要Python 2.5(因为三元运算符)?
(感谢joeforker修复了它使用键1到10而不是0到10;感谢SilentGhost:in比pythonic比on_key()或len()更多
答案 15 :(得分:0)
>>> in_list = ["a","b",None,"c"]
>>> new = ['choice ' + str(i + 1) if j is None else j for i, j in enumerate(in_list)]
>>> new.extend(('choice ' +str(i + 1) for i in range(len(new), 9)))
>>> new
['a', 'b', 'choice 3', 'c', 'choice 5', 'choice 6', 'choice 7', 'choice 8', 'choice 9']
答案 16 :(得分:0)
我还建议使用xrange而不是range。 xrange函数根据需要生成数字。范围预先生成它们。对于小型设备而言,它没有太大区别,但对于大范围而言,节省的费用可能很大。
答案 17 :(得分:0)
我的两分钱......
def extendchoices(clist):
clist.extend( [None]*(9-len(clist)) )
for i in xrange(9):
if clist[i] is None: clist[i] = "Choice %d"%(i+1)
答案 18 :(得分:0)
如果可以替换任何错误值,例如''或0
>>> mylist = ['a','b',None,'c']
>>> map(lambda a,b:a or "Choice %s"%b, mylist, range(1,10))
['a', 'b', 'Choice 3', 'c', 'Choice 5', 'Choice 6', 'Choice 7', 'Choice 8', 'Choice 9']
如果你真的只能替换无
>>> map(lambda a,b:"Choice %s"%b if a is None else a, mylist, range(1,10))
['a', 'b', 'Choice 3', 'c', 'Choice 5', 'Choice 6', 'Choice 7', 'Choice 8', 'Choice 9']
答案 19 :(得分:0)
>>> my_list=['a','b',None,'c']
>>> map (lambda x,y:x or 'Choice {}'.format(y+1),my_list,range(9))
['a', 'b', 'Choice 3', 'c', 'Choice 5', 'Choice 6', 'Choice 7', 'Choice 8', 'Choice 9']