代码之家  ›  专栏  ›  技术社区  ›  gravitation

扩展潜在不完整列表的最具python风格的方法

  •  8
  • gravitation  · 技术社区  · 15 年前

    转换的一个例子是

    ['a','b',None,'c']
    

    ['a','b','Choice 3','c','Choice 5','Choice 6','Choice 7','Choice 8','Choice 9']
    

    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赢是因为它更像蟒蛇,所以我会用它。它很容易理解并使用常见的构造。拆分这些步骤是合乎逻辑的,而且会使人一眼就能理解。

    20 回复  |  直到 15 年前
        1
  •  10
  •   ephemient    15 年前

    zip ,蟒蛇的 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 与…一样 没有一个 .

        2
  •  7
  •   Community Paul Sweatte    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

    添加了可选列表扩展

        3
  •  3
  •   Douglas Leeder    15 年前

    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 为空,则添加的选项将关闭1。

        4
  •  3
  •   Abgan    15 年前

    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)]
    
        5
  •  2
  •   Brian    15 年前

    我认为您应该将调整阵列大小视为一个单独的步骤。为此,如果数组太短,请调用 choicesTxt=choicesTxt+[None]*(10-len(choicesTxt)) . 这个 None 选择重新指定可以使用列表理解来完成。

        6
  •  2
  •   Dzinx    15 年前

    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)])
    
        7
  •  1
  •   DNS    15 年前

    我不太清楚为什么要使用range(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) ])
    
        8
  •  1
  •   Johannes Weiss    15 年前

    那怎么办呢(好像是一份口述,而不是一份清单,当它 残缺的

    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)]
    

    (感谢joeforker修复了它使用键1到10,而不再使用键0到10;感谢SilentGhost:in比_key()或len()更像pythonic)

        9
  •  1
  •   dF.    15 年前

    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的值),并在一个单独的步骤中扩展列表,我认为这更清楚。

        10
  •  1
  •   monkut    15 年前

    >>> 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']
    
        11
  •  1
  •   Ignacio Vazquez-Abrams    15 年前
    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)])
    
        12
  •  1
  •   ojrac    15 年前

    通过列表理解,您可以更简单:

    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”。

        13
  •  1
  •   joeforker    15 年前

    result 适用于Python2.4。

    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
  •   Roger Pate Roger Pate    15 年前
    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()
    
        15
  •  1
  •   John Montgomery    15 年前

    在一行中:

    [a or 'Choice %d' % i for a,i in map(None,["a","b",None,"c"],range(10))]

    尽管这将用“选项n”替换任何计算结果为False(例如None、、0等)的内容。最好换新的 "a or 'Choice %d' % i" 如果你不想要的话,用一个函数。

    关键是 map 如果参数为None,则可以将列表扩展到所需的长度,并在所需的位置设置None。

    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))]
    

        16
  •  0
  •   Arcane    15 年前

    我还建议使用xrange而不是range。xrange函数根据需要生成数字。Range会提前生成它们。对于小型设备来说,这没有多大区别,但对于大型设备来说,可以节省大量成本。

        17
  •  0
  •   SilentGhost    15 年前
    >>> 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']
    
        18
  •  0
  •   Lord British    14 年前

    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) 
    
        19
  •  0
  •   John La Rooy    13 年前

    如果可以替换任何假值,例如“”或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']
    
        20
  •  0
  •   David דודו Markovitz    8 年前
    >>> 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']