【问题标题】:If list index exists, do X如果列表索引存在,做 X
【发布时间】:2012-07-31 22:30:09
【问题描述】:

在我的程序中,用户输入数字n,然后输入n的字符串数,这些字符串存储在一个列表中。

我需要编写这样的代码,如果存在某个列表索引,则运行一个函数。

由于我已经嵌套了关于 len(my_list) 的 if 语句,这让事情变得更加复杂。

这是我现在所拥有的简化版本,但它不起作用:

n = input ("Define number of actors: ")

count = 0

nams = []

while count < n:
    count = count + 1
    print "Define name for actor ", count, ":"
    name = raw_input ()
    nams.append(name)

if nams[2]: #I am trying to say 'if nams[2] exists, do something depending on len(nams)
    if len(nams) > 3:
        do_something
    if len(nams) > 4
        do_something_else

if nams[3]: #etc.

【问题讨论】:

  • 看起来您想将 cast n 键入为整数,而不是列表。我很困惑。
  • 是的,这里真正的问题是在ifs 中使用n 而不是nams
  • 在你的情况下 n 不是一个列表。首先检查(强制转换)它是一个整数,然后你可以根据你想要达到的效果进行迭代或枚举。
  • 是的,打错了。固定为 nams[]
  • “事实上我有关于 len(my_list) 的子 if 语句。”您是否考虑过列表的len 至少是一个特定值这一事实暗示了哪些列表索引存在?

标签: python python-2.7


【解决方案1】:

使用列表len(n) 的长度来通知您的决定比检查n[i] 的每个可能长度对您来说更有用吗?

【讨论】:

  • 是的。查看代码后,我的设置完全是多余的。 len(n) 完成了我需要的一切。感谢您指出正确的方向。
  • 这不考虑负索引。我知道的最好的方法是尝试 / 除了 IndexError,但最好有一个简洁的方法来获取 bool
  • 在 Python 中,列表上的负索引只是从列表末尾倒数。所以它们不能以影响列表长度的方式存在。
【解决方案2】:

我需要编写这样的代码,如果存在某个列表索引,则运行一个函数。

这是try block 的完美用途:

ar=[1,2,3]

try:
    t=ar[5]
except IndexError:
    print('sorry, no 5')   

# Note: this only is a valid test in this context 
# with absolute (ie, positive) index
# a relative index is only showing you that a value can be returned
# from that relative index from the end of the list...

但是,根据定义,0len(the_list)-1 之间的 Python 列表中的所有项目都存在(即,如果您知道 0 &lt;= index &lt; len(the_list),则不需要 try 块)。

如果你想要 0 和最后一个元素之间的索引,你可以使用 enumerate

names=['barney','fred','dino']

for i, name in enumerate(names):
    print(i + ' ' + name)
    if i in (3,4):
        # do your thing with the index 'i' or value 'name' for each item...

如果您正在寻找一些已定义的“索引”,我认为您问错了问题。也许您应该考虑使用mapping 容器(例如字典)与sequence 容器(例如列表)。你可以像这样重写你的代码:

def do_something(name):
    print('some thing 1 done with ' + name)
        
def do_something_else(name):
    print('something 2 done with ' + name)        
    
def default(name):
    print('nothing done with ' + name)     
    
something_to_do={  
    3: do_something,        
    4: do_something_else
    }        
            
n = input ("Define number of actors: ")
count = 0
names = []

for count in range(n):
    print("Define name for actor {}:".format(count+1))
    name = raw_input ()
    names.append(name)
    
for name in names:
    try:
        something_to_do[len(name)](name)
    except KeyError:
        default(name)

这样运行:

Define number of actors: 3
Define name for actor 1: bob
Define name for actor 2: tony
Define name for actor 3: alice
some thing 1 done with bob
something 2 done with tony
nothing done with alice

您也可以使用.get 方法而不是尝试/除了更短的版本:

>>> something_to_do.get(3, default)('bob')
some thing 1 done with bob
>>> something_to_do.get(22, default)('alice')
nothing done with alice

【讨论】:

  • 尝试阻止?我是 Python 的初学者,但这似乎是编程中的一大禁忌……流控制的例外情况?例外应该是我们无法控制的事情吧?
  • @Luis 我也是 Python 的初学者,但从我所读到的这些实例中的异常处理是 Python 提倡的 C/Java/C# 不提倡的风格。见stackoverflow.com/questions/11360858/…
  • 句子“Python 列表中 0 到 len(list) 之间的所有索引”是绝对错误的。假设有一个列表 x = [1, 2, 3],其中 len_x = 3。没有像 3 这样的索引。这句话应该是:'Python 列表中的所有索引在 0 和 len(list) - 1 之间' .
  • @LiorMagen:你说得对,我编辑了它。对于这样一个迂腐的错误,要否决一个相当受欢迎的帖子有点苛刻。一个简单的评论就足够了。
  • 嗯,我有代表可以编辑,但这似乎很粗鲁。我会说类似*Note* that this approach will work whenever a value *can be looked up* by a specific index from the list. This is not quite the same as if an index exists. You can for example fetch the value at -1 (the last item) but that index does not exist. To check if an index exists use 0 &lt;= n &lt; len(lst)
【解决方案3】:

len(nams) 在你的代码中应该等于n。所有索引0 &lt;= i &lt; n“存在”。

【讨论】:

    【解决方案4】:

    只需使用以下代码即可完成:

    if index < len(my_list):
        print(index, 'exists in the list')
    else:
        print(index, "doesn't exist in the list")
    

    【讨论】:

      【解决方案5】:

      使用列表的长度将是检查索引是否存在的最快解决方案:

      def index_exists(ls, i):
          return (0 <= i < len(ls)) or (-len(ls) <= i < 0)
      

      这还测试负索引,以及大多数具有长度的序列类型(如 rangesstrs)。

      如果您之后需要访问该索引处的项目,它是easier to ask forgiveness than permission,它也更快,更 Pythonic。使用try: except:

      try:
          item = ls[i]
          # Do something with item
      except IndexError:
          # Do something without the item
      

      这与:

      if index_exists(ls, i):
          item = ls[i]
          # Do something with item
      else:
          # Do something without the item
      

      【讨论】:

        【解决方案6】:

        我需要编写这样的代码,如果存在某个列表索引,则运行一个函数。

        您已经知道如何对此进行测试,事实上已经在您的代码中执行此类测试

        长度为n 的列表的有效索引为0n-1(含)。

        因此,列表具有索引i当且仅当列表的长度至少为i + 1

        【讨论】:

        • 是的,我有解决问题的工具,只是没有清楚地应用它们。感谢您指出正确的方向。
        • 谢谢你,特别是最后一句话,这是 Python 列表的一个重要属性,它使它们不同于 JavaScript 数组和其他类似的结构。
        【解决方案7】:

        如果你想迭代插入的actors数据:

        for i in range(n):
            if len(nams[i]) > 3:
                do_something
            if len(nams[i]) > 4:
                do_something_else
        

        【讨论】:

          【解决方案8】:

          好的,所以我认为这实际上是可能的(为了争论):

          >>> your_list = [5,6,7]
          >>> 2 in zip(*enumerate(your_list))[0]
          True
          >>> 3 in zip(*enumerate(your_list))[0]
          False
          

          【讨论】:

          • 虽然这会更简单:3 in range(len(your_list)
          • 甚至这个3 in xrange(len(your_list) - 可能没有比这更好的了
          【解决方案9】:

          你可以试试这样的

          list = ["a", "b", "C", "d", "e", "f", "r"]
          
          for i in range(0, len(list), 2):
              print list[i]
              if len(list) % 2 == 1 and  i == len(list)-1:
                  break
              print list[i+1];
          

          【讨论】:

            【解决方案10】:

            Oneliner:

            do_X() if len(your_list) > your_index else do_something_else()  
            

            完整示例:

            In [10]: def do_X(): 
                ...:     print(1) 
                ...:                                                                                                                                                                                                                                      
            
            In [11]: def do_something_else(): 
                ...:     print(2) 
                ...:                                                                                                                                                                                                                                      
            
            In [12]: your_index = 2                                                                                                                                                                                                                       
            
            In [13]: your_list = [1,2,3]                                                                                                                                                                                                                  
            
            In [14]: do_X() if len(your_list) > your_index else do_something_else()                                                                                                                                                                      
            1
            

            仅供参考。恕我直言,try ... except IndexError 是更好的解决方案。

            【讨论】:

              【解决方案11】:

              这是我今天想解决这个问题的一种简单但计算效率低的方法:

              只需在 my_list 中创建一个可用索引列表:

              indices = [index for index, _val in enumerate(my_list)]
              

              那么你就可以在每个代码块之前进行测试了:

              if 1 in indices:
                  "do something"
              if 2 in indices:
                  "do something more"
              

              但任何阅读本文的人都应该从以下位置获取正确答案:@user6039980

              【讨论】:

                【解决方案12】:

                不要在括号前面留任何空间。

                例子:

                n = input ()
                         ^
                

                提示: 您应该在代码上方和/或下方添加 cmets。不在你的代码后面。


                祝你有美好的一天。

                【讨论】:

                • 欢迎来到 SO!您的回复看起来像是评论而不是答案。一旦你有足够的reputation,你就可以在任何帖子上comment。还要检查这个what can I do instead。如果您打算回答,请阅读此how-to-answer 以遵循 SO 指南。
                猜你喜欢
                • 2014-04-18
                • 1970-01-01
                • 1970-01-01
                • 2012-06-06
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多