检测项目是否是Lis中的最后一个

2024-03-29 08:33:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用Python 3,试图检测一个项是否是列表中的最后一个项,但有时会重复。这是我的代码:

a = ['hello', 9, 3.14, 9]
for item in a:
    print(item, end='')
    if item != a[-1]:
        print(', ')

我想要这个输出:

hello,
9,
3.14,
9

但我得到的结果是:

hello, 
93.14, 
9

我明白我为什么得到我不想要的输出。 如果我还可以使用循环,我会更愿意,但我可以绕过它们。(我想用更复杂的代码)


Tags: 代码inhello列表forifitemend
3条回答

在打印下一个时,请打印逗号和换行符,而不是尝试检测您是否在最后一个项目上(这仅在您在第一个项目上时需要检测):

a = ['hello', 9, 3.14, 9]
for i, item in enumerate(a):
    if i:  # print a separator if this isn't the first element
        print(',')
    print(item, end='')
print()  # last newline

enumerate()函数向每个元素添加一个计数器(请参见What does enumerate mean?),并且对于除0(第一个元素)之外的所有计数器值,if i:都是真的。

或者使用print()插入分隔符:

print(*a, sep=',\n')

在每个参数之间插入sep值(*aa中的所有值作为单独的参数应用,请参见What does ** (double star) and * (star) do for parameters?)。这比使用print(',n'.join(map(str, a)))更有效,因为这不需要首先构建一个全新的字符串对象。

虽然这些答案可能适用于OP的具体情况,但我发现它们在更广泛的应用中并不令人满意。

以下是我能想到/看到的方法以及它们各自的时间安排。

指数法

urlist_len = len(urlist)-1
for x in urlist:
    if urlist.index(x) == urlist_len:
        pass

负切片法

for x in urlist:
    if x == urlist[-1]:
        pass

枚举方法

urlist_len = len(urlist)-1
for index, x in enumerate(urlist):
    if index == urlist_len:
        pass

以下是一些不同方法的时间安排:

╔════════════════════════════════════════════════════════════════╗
║                       Timing Results (s)                       ║
╠═══════════════════════╦════╦═════════╦════════╦═══════╦════════╣
║ List size             ║ 20 ║ 200     ║ 2000   ║ 20000 ║ 200000 ║
╠═══════════════════════╬════╬═════════╬════════╬═══════╬════════╣
║                       ║ 0  ║ 0.0006  ║ 0.051  ║ 5.2   ║ 560    ║
║ Index Method          ║    ║         ║        ║       ║        ║
╠═══════════════════════╬════╬═════════╬════════╬═══════╬════════╣
║                       ║ 0  ║ 0       ║ 0.0002 ║ 0.003 ║ 0.034  ║
║ Negative Slice Method ║    ║         ║        ║       ║        ║
╠═══════════════════════╬════╬═════════╬════════╬═══════╬════════╣
║ Enumerate Method      ║ 0  ║ 0.00004 ║ 0.0005 ║ 0.016 ║ 0.137  ║
╚═══════════════════════╩════╩═════════╩════════╩═══════╩════════╝

注意:值<;10us四舍五入为0

如您所见,index方法总是要慢一些,并且它只会随着列表大小的增加而呈指数级恶化。我看没有任何理由用它。负切片方法在所有情况下都是最快的,但是如果列表中有重复项,它将给您一个假阳性。此外,负切片方法要求正在迭代的序列支持索引。因此,如果列表中有重复项(或不支持索引序列),请使用快速但不是最快的枚举方法。

编辑:正如一位评论员指出的那样,计算循环中列表的长度并不理想。利用这一知识,我可以将枚举方法(目前未反映在表中)减少35%。


tldr:如果所有元素都是唯一的并且序列支持索引,则使用负切片,否则使用枚举方法

如果您真的只想将元素连接到逗号+换行符分隔的字符串中,那么使用^{}方法更容易:

elements = ['hello', 9, 3.14, 9]
s = ',\n'.join(str(el) for el in elements)
# And you can do whatever you want with `s` string:
print(s)

相关问题 更多 >