我有这样的事情:
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
。 (迭代会停止吗?)那么,最好的做法是什么?我想不出一个简短的方法。基本上我需要的是:
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
。但事实上,一般来说,我将拥有超过一百个价值观。
编辑:通过说“可以为空”,我的意思是说索引可能超出了列表的大小。
edit2: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))
答案 0 :(得分:2)
你会采取不同的方法;您将对原始列表进行切片,并使用csv
module来处理制表符分隔和换行符:
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
模块,但可以使用其他采用任意元素列表的技术。例如str.join()
:
'\t'.join(['Price'] + foo[i:i + 5] + ['Value']) + '\n'
将生成一个制表符分隔值的字符串,并附加换行符。这确实要求传递给str.join()
的列表中的所有值都已经是字符串。
答案 1 :(得分:1)
我的建议是,不要依赖索引,而是围绕数据构建代码。如果您没有编制索引,那么您将永远不会遇到IndexError
中的问题考虑大小为L
的列表N
,将其平均分配为n
。此问题有各种accepted solutions and approaches
我通常宣讲的那个(尽管你可以自由接受任何替代方法)是
izip_longest(*[iter(L)]*n)
所以给定一个列表
L = [a 1 , 2 , 3 ... a N ]
这将生成⌊N/n⌋大小相等的块。大小为Mod(N, n)
的最后较短列表将附加填充符,默认情况下为无
L = [[a 1 ,a 2 ,a 3 ... a n ], [a 1 , 2 , 3 ... a n ],[a 1 , 2 , 3 ... a n ] ,.(N Items).. [a 1 , 2 ,.. a N%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
答案 2 :(得分:0)
这取决于foo
是什么。如果是list
或tuple
,则不会有空索引。如果是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
答案 3 :(得分:0)
要扩展我的评论,您可以实现以下内容:
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'
但是,我怀疑这是一个XY problem - 如果您提供更多背景信息,我们很可能会帮助您提出一种完全消除此问题的不同方法。