python - 将两个列表之间的数据排序到一个新列表中,并使用新列表中保存的数据格式化字符串列表

标签 python sorting nested-loops string-formatting nested-lists

抱歉,如果这不是很清楚,这是我第一次在这里提问,所以我希望我能正确解释我的问题。

我有以下具有不同值的列表:

A_list = ['A', 'A', 'B', ['C', 'D'] ]
B_list = ['A1', 'W5', 'X6', 'A2', 'A3', 'T5', 'B0', 'Z9', 'C1', 'W3', 'D1']
C_list = []
string_list = ["{0} in Alpha", "{0} in Apple", "{0} in Bee", "{0} in Cheese and {1} in Dice"]

我需要在 B_list 中找到 A_list 的元素,将它们附加到 C_list,并让输出为 string_list 中的格式化字符串以及 C_list 中的元素。

因此,在 B_list 中查找 A_list[i] 后,C_list 最终会是这样的:

C_list = ['A1', 'A2', 'A3', 'B0', ['C1', 'D1']]

输出将是这样的:

A1 in Alpha,
A1 in Apple,
A2 in Alpha,
A2 in Apple,
A3 in Alpha,
A3 in Apple,
B0 in Bee,
C1 in Cheese and D1 in Dice

我一直在用嵌套列表绞尽脑汁,并以与 A_list 类似的顺序获取它们,以便能够使用以下内容格式化输出:

output = string_list[i].format(*C_list[i])//只是一个示例

我一直在尝试使用 for 循环和 if 语句的组合来解决这个问题。 我可以在一个简单的 for 循环中搜索 B_listA_list 的元素:

for a in A_list:
    for b in B_list:
        if a in b:
            print(str(a) + " found in " + str(b))

令我烦恼的是如何将 B_list 中找到的元素添加到与 A_list 类似的格式中,这样我最终可能会得到

C_list = ['A1', 'A2', 'A3', 'B0', ['C1', 'D1']]

而不是这个:

C_list = ['A1', 'A2', 'A3', 'B0', 'C1', 'D1']

最佳答案

第 1 部分:获取 C_list

您必须自己创建嵌套列表才能附加到 C_list。 如果 a 中的一项可以是字符串列表或字符串,则有 2 种情况。

def get_A_in_B(a_list:"list[str|list[str]]",b_list:"list[str]"):
    c_list = [] # global within this function     
    
    # for neatness   
    def process_base_item(a_str:"str",out_list:"list"):
        matches = sorted([b_str for b_str in b_list if b_str.startswith(a_str)])
        out_list.extend(matches)
    
    for a_item in a_list: # case 1 - is list, extend nested
        if type(a_item) is list:
            sublist = a_item
            nested_list = []
            for sub_item in sublist:
                process_base_item(sub_item,nested_list)
            if nested_list:
                c_list.append(nested_list)
        else: # case 2 - is string, extend c list
            process_base_item(a_item,c_list)
    return c_list

用法:

A_list = ['A', 'B', ['C', 'D'] ]
B_list = ['A1', 'W5', 'X6', 'A2', 'A3', 'T5', 'B0', 'Z9', 'C1', 'W3', 'D1']
C_list = get_A_in_B(A_list,B_list,string_list)

输出:

['A1', 'A2', 'A3', 'B0', ['C1', 'D1']]

第 2 部分:格式化

如果两个假设成立,这就会起作用:

  1. 假设格式字符串中每种类型的字母只有一个
  2. 假设如果嵌套不均匀,您是否想循环遍历所有可能性 例如[“C1”,“C2”,“D1”] =>“C1”+“D1”,“C2”+“D1”

这是真正棘手的部分。我使用正则表达式将字母与格式字符串进行匹配。

对于C_list的嵌套列表,我将它们按字母分成更多子列表,然后得到它们的 cartesian product作为格式字符串的多个参数输入。

和以前一样,你有 2 个案例。

def format_string_list(c_list,string_list):
    formatted_string_list = []
    for c_item in c_list:
        for fmt_str in string_list:
            if type(c_item) is list: # case 1 - is list, match multiple
                c_sublist = c_item
                # assumption 1: letters are unique
                first_letters = sorted(set([c_str[0] for c_str in c_sublist]))
                matched_letters = []
                for letter in first_letters:
                    pat = f" in {letter}"
                    if pat in fmt_str:
                        matched_letters.append(letter)
                        
                if first_letters==matched_letters: 
                    # get dictionary of lists, indexed by first letter
                    c_str_d = {}
                    for letter in first_letters:
                        c_str_d[letter] = [c_str for c_str in c_sublist if letter in c_str]
                    
                    # assumption 2: get all combinations
                    for c_str_list in itertools.product(*c_str_d.values()):
                        c_fmtted = fmt_str.format(*c_str_list)
                        formatted_string_list.append(c_fmtted) 
            else: # case 2
                c_str = c_item
                first_letter = c_str[0]
                pat = f" in {first_letter}"

                if pat in fmt_str:
                    c_fmtted = fmt_str.format(c_str)
                    formatted_string_list.append(c_fmtted)
    
    return formatted_string_list

用法:

C_list = ['A1', 'A2', 'A3', 'B0', ['C1', 'D1'] ]
string_list = ["{0} in Alpha", "{0} in Apple", "{0} in Bee", "{0} in Cheese and {1} in Dice"]
formatted_string_list = format_string_list(C_list,string_list)
# print output
print("\n".join(formatted_string_list))

输出:

A1 in Alpha
A1 in Apple
A2 in Alpha
A2 in Apple
A3 in Alpha
A3 in Apple
B0 in Bee
C1 in Cheese and D1 in Dice

也适用于更复杂的情况

不会超出一级嵌套,您认为您的案例不需要它

A_list = ['A', 'B', ['C', 'D', 'E']]
B_list = ['A1', 'W5', 'X6', 'D2', 'E1', 'A2', 'A3', 'T5', 'E2', 'B0', 'Z9', 'C1', 'W3', 'D1']
string_list = ["{0} in Alpha", "{0} in Apple", "{0} in Bee", "{0} in Cheese and {1} in Dice {2} in Egg"]

输出:

['A1', 'A2', 'A3', 'B0', ['C1', 'D1', 'D2', 'E1', 'E2']]
A1 in Alpha
A1 in Apple
A2 in Alpha
A2 in Apple
A3 in Alpha
A3 in Apple
B0 in Bee
C1 in Cheese and D1 in Dice E1 in Egg
C1 in Cheese and D1 in Dice E2 in Egg
C1 in Cheese and D2 in Dice E1 in Egg
C1 in Cheese and D2 in Dice E2 in Egg

关于python - 将两个列表之间的数据排序到一个新列表中,并使用新列表中保存的数据格式化字符串列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75959506/

相关文章:

python - 重命名Python中的符号链接(symbolic link)

algorithm - 从随机有序子集重建超集

python - 使用python请求增加504超时之前的时间

java - 对数组而不是 ArrayList 进行排序

java - 按 String[] 中存在的名称按升序对 HashMap<String[], Boolean> 进行排序

javascript - 在没有太多嵌套循环的情况下在多维数组中查找匹配元素?

java - 我无法阻止 null 显示在 java 中的一维数组的输出中

python - 使用 Itertools 实现具有内部中断的可变级别嵌套循环

python - 如何在 tkinter 中使用 grid() 方法在新小部件上创建按钮?

python - 如何从类本身实例化类的对象?