【问题标题】:returnig elements in a list with their positions in that list返回列表中的元素及其在该列表中的位置
【发布时间】:2015-03-25 02:49:33
【问题描述】:

我有一个列表,我想返回该列表中的每个元素及其在其中的位置。

例如:

my_enumerate(['dog', 'pig', 'cow']) 

应该返回:

[(0, 'dog'), (1, 'pig'), (2, 'cow')]

以下是我的处理方式:

def my_enumerate(items):
''' returning position of item in a list'''
lista = []
for num in range(0, len(items)+1):
    for item in items:
        lista.append("({0}, {1})".format(num, item))
return lista

返回给我:

['(0, dog)', '(0, pig)', '(0, cow)', '(1, dog)', '(1, pig)', '(1, cow)', '(2, dog)', '(2, pig)', '(2, cow)', '(3, dog)', '(3, pig)', '(3, cow)']

该函数的行为应该与内置的 enumerate 函数完全相同,但我不允许使用它。

【问题讨论】:

    标签: python list loops python-3.x indexing


    【解决方案1】:

    您的程序生成列表中所有索引和元素的笛卡尔积。它获取每个索引并使用列表中的元素生成所有字符串。另外,请注意,您应该只迭代到列表的长度,当您执行len(items) + 1 时,您实际上超出了列表的实际长度。

    你只能使用第一个循环,像这样

    >>> def my_enumerate(items):
    ...     lista = []
    ...     for num in range(len(items)):
    ...         lista.append("({0}, {1})".format(num, items[num]))
    ...     return lista
    ... 
    >>> my_enumerate(['dog', 'pig', 'cow']) 
    ['(0, dog)', '(1, pig)', '(2, cow)']
    

    你也可以使用简单的list comprehension,像这样

    >>> def my_enumerate(items):
    ...     return ["({0}, {1})".format(num, items[num]) for num in range(len(items))]
    ... 
    >>> my_enumerate(['dog', 'pig', 'cow']) 
    ['(0, dog)', '(1, pig)', '(2, cow)']
    

    注意 1: 在 Python 3.x 中,除非必要,否则不必使用格式字符串中的位置。所以,"({}, {})".format 就足够了。

    注意2:如果你真的想返回元组,比如enumerate,那么你不应该使用字符串格式,而是像这样准备元组

    >>> def my_enumerate(items):
    ...     return [(num, items[num]) for num in range(len(items))]
    ... 
    >>> my_enumerate(['dog', 'pig', 'cow']) 
    [(0, 'dog'), (1, 'pig'), (2, 'cow')]
    

    注意 3:如果你真的想模拟 enumerate 就像它在 Python 3.x 中一样,那么你最好使用生成器函数,像这样

    >>> def my_enumerate(items):
    ...     for num in range(len(items)):
    ...         yield (num, items[num])
    ...     
    ... 
    >>> my_enumerate(['dog', 'pig', 'cow']) 
    <generator object my_enumerate at 0x7f5ff7abf900>
    >>> list(my_enumerate(['dog', 'pig', 'cow']))
    [(0, 'dog'), (1, 'pig'), (2, 'cow')]
    

    注4:更好的消息是,你可以写同样的my_enumerate,用yield fromgenerator expression,像这样

    >>> def my_enumerate(items):
    ...     yield from ((num, items[num]) for num in range(len(items)))
    ... 
    >>> my_enumerate(['dog', 'pig', 'cow']) 
    <generator object my_enumerate at 0x7f5ff7abfe10>
    >>> list(my_enumerate(['dog', 'pig', 'cow']))
    [(0, 'dog'), (1, 'pig'), (2, 'cow')]
    

    【讨论】:

    • 谢谢!但是出现在元组周围的字符串呢?我怎样才能删除它们并将它们放在元组内的item 周围。 (与 Top 示例相同)。
    • @Moh'dH 请查看最新答案中的“注2”。
    【解决方案2】:

    如果你把它写成一个生成器,它甚至可以和无限的生成器一起工作:

    def my_enumerate(items):
        i = 0
        for e in items:
            yield (i, e)
            i += 1
    
    print(list(my_enumerate(['dog', 'pig', 'cow']))
    

    【讨论】:

      【解决方案3】:

      您可以使用ziprangelen 轻松地在单行中完成:

      def my_enumerate(items):
          return zip(range(len(myList)), myList)
      
      my_list = ['dog', 'pig', 'cow']
      print(my_enumerate(my_list)) # prints [(0, 'dog'), (1, 'pig'), (2, 'cow')]
      

      以上将是 Python 2 版本。请注意,在 Python 3 中,zip 返回一个生成器,这实际上可能正是您所需要的,但如果您绝对需要一个列表,您可以将返回的表达式包装在 list() 调用中。

      【讨论】:

      • 你打败了我。我认为这是最优雅的解决方案。并将其封装在一个函数中,我们可以这样做:my_enumeration = lambda li : zip(range(len(li)), li)。不过,您不需要list() 的返回值zipzip 返回一个列表。
      • @szabad 啊,抱歉,我在 repl.it 上使用 Python 3,而在 Python 3 中,zip 返回一个生成器/可迭代对象。但我已经在我的回答中做了说明。
      【解决方案4】:

      最简单的:

      def my_enumerate(items):
          return list(enumerate(items))
      

      【讨论】:

      • 其实OP说的是The function should behave exactly like the built-in enumerate function, but I'm not allowed to use it.
      • 我想用钉子开车,但我不允许使用锤子(即使我有锤子)。我不会解释为什么我不能使用锤子。
      • @wim 我在大学里学会了实现大部分 C++ stdlib,我可以轻松地说这是我一生中最有启发性的经历之一,它让我对算法和数据结构非常感兴趣。为教育目的重新发明轮子并不总是一件坏事。
      猜你喜欢
      • 2013-03-24
      • 2021-12-19
      • 1970-01-01
      • 2018-11-22
      • 1970-01-01
      • 1970-01-01
      • 2020-01-25
      • 2011-01-09
      • 1970-01-01
      相关资源
      最近更新 更多