Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python-检查列表的索引元素是否存在-最佳实践?_Python_List_Python 3.x_Element - Fatal编程技术网

Python-检查列表的索引元素是否存在-最佳实践?

Python-检查列表的索引元素是否存在-最佳实践?,python,list,python-3.x,element,Python,List,Python 3.x,Element,我有这样的想法: for i in range(0,100,5): text = ("Price\t", foo[i+0].bar, "\t", foo[i+1].bar, "\t", foo[i+2].bar, "\t", foo[i+3].bar, "\t", foo[i+4].bar, "\t", "Value", "\n")

我有这样的想法:

for i in range(0,100,5):

    text = ("Price\t",
            foo[i+0].bar, "\t",
            foo[i+1].bar, "\t",
            foo[i+2].bar, "\t",
            foo[i+3].bar, "\t",
            foo[i+4].bar, "\t",
            "Value", "\n")

    file.writelines(text)
我的问题是:假设
i=0
。在这种情况下,我肯定会有foo[0]。但对于指数1、2、3、4,foo可以为空。例如,如果索引大于2时foo为空,我希望我的文本如下:

text = ("Price\t",
        foo[0].bar, "\t",
        foo[1].bar, "\t",
        foo[2].bar, "\n")
我曾想过使用异常,但我想,如果没有所有索引元素,我将无法构造
文本。(迭代将停止?)那么,这样做的最佳实践是什么?我想不出一条捷径来做这件事。基本上我需要的是:

text= ("Price\t",
        ifexist(foo[0].bar, "\t"),
        ifexist(foo[1].bar, "\t"),
        ifexist(foo[2].bar, "\t"),
        ifexist(foo[3].bar, "\t"),
        ifexist(foo[4].bar, "\t"),
        "Value", "\n")
ps:为了简单起见,请不要忘记我假设的
I=0
。但事实上,一般来说,我会有上百个值

编辑:我说“可以是空的”,意思是索引可能超出了列表的大小

编辑2:Abot foo:

# start class
class Test:
    def __init__(self, bar, bar2, bar3):
        self.bar= a
        self.bar2= b
        self.bar3= c

# end class    


for i in particular_list:
    # read and parse the input file with indeces obtained from particular_list
    # do calculations for temp_bar,temp_bar2,temp_bar3
    foo.append(Test(temp_bar, temp_bar2, temp_bar3))

你会采取不同的方法;您将对原始列表进行切片,并使用来处理选项卡定界和换行:

import csv

with open('outputfile', 'w', newline='') as file:
    writer = csv.writer(file, delimiter='\t')
    for i in range(0, 100, 5):
        row = foo[i:i + 5]
        writer.writerow(['Price'] + row + ['Value']) 
对列表进行切片始终会返回一个新的列表对象,但如果在有效范围之外使用切片索引,则结果是一个较短或为空的列表:

>>> foo = ['spam', 'ham', 'eggs']
>>> foo[0:5]
['spam', 'ham', 'eggs']
>>> foo[5:10]
[]
同时,
csv.writer()
对象负责将列表作为制表符分隔的字符串以及换行符写入文件

与使用
csv
模块不同,您仍然可以使用切片,但可以使用其他技术获取任意元素列表。例如:

'\t'.join(['Price'] + foo[i:i + 5] + ['Value']) + '\n'

将生成一个由制表符分隔的值组成的字符串,并附加一个换行符。这确实要求传递给
str.join()
的列表中的所有值都已经是字符串。

这取决于
foo
是什么。如果是
列表
元组
,则不会有空索引。如果是
dict
,引用未知密钥将导致
KeyError
异常

假设
foo
是一个元组列表,您可以轻松地打印它

In [3]: t = range(30)

In [4]: p = [tuple(t[i:i+3]) for i in range(0, len(t), 4)]

In [5]: p
Out[5]: [(0, 1, 2), (4, 5, 6), (8, 9, 10), (12, 13, 14), (16, 17, 18), (20, 21, 22), (24, 25, 26), (28, 29)]
您可以迭代该元组列表并打印它们

In [6]: for k in p:
    print '\t'.join(['Price'] + [str(i) for i in k] + ['Value'])
   ...:     
Price   0   1   2   Value
Price   4   5   6   Value
Price   8   9   10  Value
Price   12  13  14  Value
Price   16  17  18  Value
Price   20  21  22  Value
Price   24  25  26  Value
Price   28  29  Value

要扩展我的评论,您可以实现如下内容:

def if_exist(seq, index, attr, default):
    """Return seq[index].attr or default."""
    try:
        return getattr(seq[index], attr)
    except IndexError:
        return default
你可以使用它,比如:

if_exist(foo, 0, "bar", "\t")
演示:

>>> if_exist([1, 2, 3], 4, "bar", "\n")
'\n'

然而,我怀疑这是一个问题——如果您提供更多的背景信息,我们可能会帮助您提出一种完全解决此问题的不同方法。

我的建议是,不要依赖索引,而是围绕数据构建代码。如果您没有索引,那么在IndexError中就永远不会有问题

考虑将一个大小为
N
的列表
L
按大小
N
平均划分。这个问题有多种原因

我通常鼓吹的方法(尽管你可以自由接受任何其他方法)是

所以给出了一个清单

L=[a1,a2,a3…aN]

这将产生⌊不适用⌋ 大小相同的块。最后一个较短的size
Mod(N,N)
列表将附加一个填充符,在本例中默认为None

L=[[a1,a2,a3…an],[a1,a2,a3…an],[a1,a2,a3…an],(N项)…[a1,a2,…an%N],无,无(N项)]

现在,只需遍历这个列表,忽略子列表中的任何
Nones

演示

from itertools import izip_longest
class Foo(object):
    def __init__(self, n):
        self.bar = n
foo = [Foo(i) for i in range(12)]
for rows in izip_longest(*[iter(foo)]*5):
    print "Price\t{}".format('\t'.join(str(row.bar)
                       for row in rows
                       if row is not None))
输出

Price   0   1   2   3   4
Price   5   6   7   8   9
Price   10  11

最简单的解决方法是
尝试
,然后捕获
索引器之外的
。但是你最好改变你的数据结构,比如元组列表而不是一个长而平的列表。你说的
空是什么意思?你的意思是索引超出了列表的大小吗?或者
foo[4]
的值是
None
?或者
foo[4]
的值是
'
?@jornsharpe使用类结构来存储元素似乎是一件很好的事情。但是,这是一个直觉的决定。我尝试使用try&except indexer,但是在这种情况下,如果缺少一个元素,我将丢失
文本。你能告诉我怎么用吗?@Robᵩ 我想说的是索引是否超出了列表的大小。谢谢,我将编辑这个问题。@FrankBrewer您的
Test
类可能是一个元组,因为它不包含任何方法。这将使
foo
成为一个元组列表,可以通过迭代列表和
join
-ing元组轻松处理。添加了关于
foo
Price   0   1   2   3   4
Price   5   6   7   8   9
Price   10  11