Python 列表从第二个维度中进行选择,其中第一个维度 = 条件



假设我有一个值的 2D 列表

[[00000.ppm,11],[00001.ppm,40],[00001.ppm,38],[

00001.ppm,13],00002.ppm,39],[00003.ppm,4]]

我需要从列表中的列表的第二个维度中选择每个值,其中文件 = "anything.ppm">

因此,当我搜索 00001.ppm 时,我会得到值"40"、"38"、"13"作为输出

此外,我需要将这些值分开,以便我可以比较它们,例如

_class=13
if (value==_class): do something

我在想是否有其他方法,而不仅仅是昂贵的循环遍历整个列表,因为事实上 - 文件是有序的,它们的名称始终是 int 增量。

我只是不知道每个文件有多少个。

也许为此将.csv文件读取到列表中是一个坏主意。

.csv格式

00000.ppm,11
00001.ppm,40
00001.ppm,38
00001.ppm,13
00002.ppm,39
00003.ppm,4

我在想是否有其他方法,而不仅仅是昂贵的循环 通过整个列表,因为事实上 - 文件是有序的,并且 它们的名称始终是整数增量。

您可以利用文件对象可迭代的事实,并在从 00001 转换到 00002 时停止从中读取,而不是将整个数据集读取到列表并对其进行传递。

def read_partial(file, key='00001.ppm'):
with open('obj.csv') as f:
found = False
for line in f:
if line.startswith(key):
yield int(line.split(',')[-1].strip())
found = True
else:
if found:
break 

>>> list(read_partial('obj.csv'))
[40, 38, 13]

同样,这假设 0000x.ppm 字段的排序与您的问题相同。

obj.csv:

00000.ppm,11
00001.ppm,40
00001.ppm,38
00001.ppm,13
00002.ppm,39
00003.ppm,4

如果确实要采用遍历列表的路线,可以使用[b for a, b in mylist if a == '00001.ppm']

听起来您想获取与特定文件名对应的所有值的列表。如果您没有很多项目和/或想要检查所有文件名,那么最好的办法可能是使用 for 循环将所有相关值分组到字典中。但是,如果您有一个很长的排序项目列表,并且您只想检查一些文件名,那么您可以使用bisect模块非常快速地搜索列表。

下面的代码给出了这两种方法的示例。

entries = [
['00000.ppm', 11],
['00001.ppm', 40], ['00001.ppm', 38], ['00001.ppm', 13],
['00002.ppm', 39],
['00003.ppm', 4]
]
# good for most cases:
values = dict()
for filename, value in entries:
values.setdefault(filename, []).append(value)
print(values['00001.ppm'])
# [40, 38, 13]
# not clear what you want to do with these next...
# this method searches within a sorted list.
# it will be useful if there are many items in the entries list (> ~100000) 
# and you only need to lookup a few
import bisect
def find_values(entries, filename):
starting_search_key = [filename, -1]
i = bisect.bisect_left(entries, starting_search_key)
values = []
while i < len(entries) and entries[i][0] == filename:
values.append(entries[i][1])
i += 1
return values
print(find_values(entries, '00001.ppm'))
# [40, 38, 13]

或者,Pandas 包可能是一个更好的全方位选择,因为它可以非常快速地读取 csv 文件,并且可以对结果数据进行索引搜索。下面是一些代码:

import pandas as pd
entries = pd.read_csv('myfile.csv', index_col=0, names=['filename', 'class'])
print(list(entries.loc['00001.ppm', 'class']))

如果你有一个巨大的csv文件,只需要做几次搜索,你可以使用平分算法非常快速地搜索,而无需读取大部分文件。但是您可能必须自己实现算法,而不是使用平分模块。您必须打开文件,然后使用file.seek()跳到中间,然后向前扫描直到到达回车符,然后检查下一个文件名是否小于您要查找的文件名。如果是这样,请向前跳一半;如果没有,请跳到一半。重复此操作,直到找到您感兴趣的文件名。但是这有复杂的边缘情况,除非您有一个非常大的csv文件并且只需要对其进行一些搜索,否则我不会追求它。更好的选择是使用数据库和/或 Dask 包。

我认为没有办法在不循环数组的情况下做到这一点。

您可以使用本答案中所示的方法。这里

[ i for i, word in enumerate(my_list[:][0]) if word == 'something.ppm' ]

应该给你数组中元素的索引。然后,您可以使用这些索引在第二列中获取相应的值:

my_list[i][1]

最新更新