【问题标题】:Indexing into a list using a sorting function on strings使用字符串上的排序函数索引到列表中
【发布时间】:2022-11-18 23:46:28
【问题描述】:

我有一个现有的字符串列表,我正在从遵循命名约定的 CSV 中读取这些字符串,例如......

["",
"00000-ABC-XX-00-DR-A-20100",
"00000-ABC-XX-01-DR-A-20101",
"00000-ABC-XX-02-DR-A-20102",
"",
"00000-ABC-XX-ZZ-DR-A-20350",
"00000-ABC-XX-ZZ-DR-A-20351",
"00000-ABC-XX-ZZ-DR-A-20352",
""]

给定列表中尚未出现的新字符串列表,我想知道如果以保留顺序编号的方式插入,它们将放置在列表中的哪个索引处。就好像它们是由 list.sort() 组织的一样。

我不能使用 list.sort 的原因是它将代表 CSV 中的行间隙的所有空字符串值分成一组,然后是排序后的字符串。

例如,如果我想插入以下 2 个值...

["00000-ABC-XX-ZZ-DR-A-20300","00000-ABC-XX-ZZ-DR-A-20301"]

现有列表现在看起来像这样......

["",
"00000-ABC-XX-00-DR-A-20100",
"00000-ABC-XX-01-DR-A-20101",
"00000-ABC-XX-02-DR-A-20102",
"",
"00000-ABC-XX-ZZ-DR-A-20300",
"00000-ABC-XX-ZZ-DR-A-20301",
"",
"00000-ABC-XX-ZZ-DR-A-20350",
"00000-ABC-XX-ZZ-DR-A-20351",
"00000-ABC-XX-ZZ-DR-A-20352",
""]

是否有一个智能的list.sorted参数可以返回这两个新行的索引,或者我是否需要编写一个函数?

提前致谢。

【问题讨论】:

  • 您无需再次排序即可从已排序列表中找到索引。
  • 您可以使用 sortdata.sort(key=functools.cmp_to_key(lambda a, b: 0 if not a or not b else 1 if a > b else -1 if a < b else 0)) 将空字符串视为等于任何相邻字符串,但是空字符串相对两侧的数字字符串组不一定会相对于彼此正确排序。
  • 只是我的两分钱,但我觉得在你的列表中保持行间距只会让你的生活更加艰难。 CSV 数据没有办法表示除此之外的数据分组,但在 Python 世界中你当然可以 - 也许考虑列表的列表,或者类似的东西?不知道行间隙意味着什么就很难具体说,但是您可以保留该信息,而不必在每种情况下都围绕它进行编码。

标签: python list sorting indexing


【解决方案1】:

bisectkey 函数一起使用会找到插入点:

from bisect import bisect
from functools import cmp_to_key

data = [
    "",
    "00000-ABC-XX-00-DR-A-20100",
    "00000-ABC-XX-01-DR-A-20101",
    "00000-ABC-XX-02-DR-A-20102",
    "",
    "00000-ABC-XX-ZZ-DR-A-20350",
    "00000-ABC-XX-ZZ-DR-A-20351",
    "00000-ABC-XX-ZZ-DR-A-20352",
    "",
]

key_func = cmp_to_key(
    lambda a, b: 0 if not a or not b else 1 if a > b else -1 if a < b else 0
)
for val in ["00000-ABC-XX-ZZ-DR-A-20300","00000-ABC-XX-ZZ-DR-A-20301"]:
    data.insert(bisect(data, key_func(val), key=key_func), val)

print(*data, sep="
")

00000-ABC-XX-00-DR-A-20100
00000-ABC-XX-01-DR-A-20101
00000-ABC-XX-02-DR-A-20102

00000-ABC-XX-ZZ-DR-A-20300
00000-ABC-XX-ZZ-DR-A-20301
00000-ABC-XX-ZZ-DR-A-20350
00000-ABC-XX-ZZ-DR-A-20351
00000-ABC-XX-ZZ-DR-A-20352

请注意,找到两个新字符串的插入点本身并不会插入一个新的非序列号之间的空字符串,如您的示例所示。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-29
    • 2017-05-18
    • 2019-08-28
    • 2011-07-05
    • 2020-08-15
    • 1970-01-01
    • 2014-07-02
    • 2017-07-22
    相关资源
    最近更新 更多