简体   繁体   English

遍历多个字符串列表以找到一个公共值

[英]iterate through multiple lists of strings to find a common value

I'm trying to come up with something to find the substring 'angle' in each of these lists of strings: 我试图提出一些在每个字符串列表中找到子字符串“ angle”的方法:

ListA = ['angle 45', 'color red', 'inside t']

ListB = ['angle 135', 'color blue', 'inside f']

ListC = ['above r', 'angle 315', 'color pink', 'inside o']

I need to add a couple checks 我需要添加几张支票

1) only if 'angle' exists in all 3 lists 1)仅在所有3个列表中都存在“角度”时

2) And if listA's 'angle' value does not equal listC's angle value, 2)如果listA的“角度”值不等于listC的角度值,

Then get listC's angle value, subtract 90 and put the new string back in the list. 然后获得listC的角度值,减去90,然后将新字符串放回列表中。 So, listC would now look like: 因此,listC现在看起来像:

ListC = ['above r', 'angle 225', 'color red', 'inside r']

I've tried splitting these lists on white space to create lists like: 我试过在空白处拆分这些列表以创建类似以下的列表:

['angle', '45', 'color', 'red', 'inside', 't']

However, i'm having difficulty iterating through all 3 lists, then doing the subsequent checks, pulling a value and replacing. 但是,我很难遍历所有3个列表,然后进行后续检查,提取值并替换。 I'm wondering if I need to create a new dictionary or list to be able to fully implement this. 我想知道是否需要创建新的字典或列表才能完全实现此目的。

Update This is what I have that checks for 'angle ' in all three lists then splits up each list further. 更新这就是我检查所有三个列表中的“ angle”,然后进一步拆分每个列表的内容。 What I haven't figured out is now that i've split angle from it's value, i'm not sure how I check that listA's angle value does not equal listB's. 我还没有弄清楚的是,现在我已经将角度值与其分开了,我不确定如何检查listA的角度值不等于listB的角度。 I haven't gotten to pulling the value, updating it and putting it back. 我还没有去拉取价值,更新它并放回它。

if any("angle " in s for s in listA) and any("angle " in s for s in listB) \
    and any("angle" in s for s in listC):
    listASplit = []
    for word in listA:
        word = word.split(" ")
        listASplit.extend(word)

    listBSplit = []
    for word in listB:
        word = word.split(" ")
        listBSplit.extend(word)

    listCSplit = []
    for word in listC:
        word = word.split(" ")
        listCSplit.extend(word)

You've got a lot going on here, but I would agree that a dictionary would be better here. 您在这里进行了很多工作,但是我同意在这里使用字典会更好。

To start with, let's parse the list 首先,让我们分析列表

dictA = {}

for item in ListA:
    row = item.split(" ")
    dictA[row[0]] = row[1] 

Do the same with each list, then you can compare values of the dictionaries without looping further. 对每个列表执行相同的操作,然后可以比较字典的值而无需进一步循环。

if dictA['angle'] != to dictC['angle']:
    ...dostuff...

Don't forget to cast to the appropriate type when nessesary 必要时别忘了强制转换为适当的类型

lista = ['angle 45', 'color red', 'inside t'] 
listb = ['angle 135', 'color blue', 'inside f'] 
listc = ['above r', 'angle 315', 'color pink', 'inside o']
kw = 'angle'
results = []

for item in lista:
    if kw in item:
        results.append(item)
for item in listb:
    if kw in item:
        results.append(item)
for x in range(len(listc)):
    if kw in item[x]:
        results.append(item)
        index = x

if int(results[0].split()[1]) != int(results[2].split()[1]):
    lastindex = results[2].split()
    listc[index] = lastindex[0]+' '+str(int(lastindex[1])-90)
for x in results:
    print(x)

So explained: 如此解释:

I added a new variable called kw and this just hold the keyword we are searching for. 我添加了一个名为kw的新变量, kw包含我们要搜索的关键字。

I also created an empty list called results to store the matches and their values. 我还创建了一个名为results的空列表,用于存储匹配及其值。

When we iterate listc we iterate the range of the length of the list so that we can extract an index (to replace the string later). 当我们迭代listc我们迭代列表长度的范围,以便我们可以提取索引(以后替换字符串)。

So, we check all of the lists for the keyword and append() the match to results 因此,我们检查所有列表中的关键字, append()results匹配

After that, we check that the first and last values DO NOT match. 之后,我们检查第一个和最后一个值是否不匹配。 If this is true, then we can split the string we extracted from listc and then minus 90 from the value before joining it back together and replacing the string in listc 如果是这样,那么我们可以拆分从listc提取的字符串,然后从该值中减去90,然后再将其重新连接在一起并替换为listc的字符串。

def f(l):
    cnt  = 0
    for el in l:
        cnt+= len([x for x in el if 'angle' in x])
    if cnt == 3:
        if l[0][0] != l[1][0]:
            angle = l[2][1]
            n, d = angle.split()
            d = str(int(d) - 90)
            angle = n + " " + d
    l[2][1] = angle
    return l[2]

f([ListA, ListB, ListC])  

['above r', 'angle 225', 'color pink', 'inside o'] ['r上方','角度225','粉红色','内侧o']

Compartmentalize your work via functions: 通过功能对您的工作进行分区:

def index_of_angle(lst):
    for string in lst:
        if string.startswith("angle"):
            return lst.index(string)
    # implicitly returns None if angle is not found

def get_angles(*lsts):
    return [index_of_angle(lst) for lst in lsts]

Now this is easy to follow: 现在这很容易理解:

a, b, c = get_angles(ListA, ListB, ListC)

if None not in [a, b, c]:  # Check 1 is obvious
    if ListA[a] != ListC[c]:  # Check 2 is obvious
        new_angle = int(ListC[c].split()[1]) - 90  # split by default is on spaces
        ListC[c] = "angle %d" % new_angle

To be even more explicit, you could rename get_angles to get_angles_or_none to make it clear it gives None if no angle is found. 为了更加明确,您可以将get_angles重命名为get_angles_or_none ,以清楚地表明如果未找到角度则给出None


To handle input where angle may appear more than once (and this input should be discarded): 处理角度可能不止一次出现的输入(并且应丢弃此输入):

def index_of_angle(lst):
    index_found = None
    for string in lst:
        if string.startswith("angle"):
            if index_found is not None:
                index_found = None  # if multiple angles found, set return to None
                break  # if two angles found, no need to keep looking
            index_found = lst.index(string)
    return index_found # returns angle or None if not found/multiple

This will be marginally slower, as we cannot return once we find angle (we must instead ensure that another angle entry does not exist first). 这将稍微慢一些,因为一旦找到角度我们就无法返回(必须确保首先不存在另一个角度输入)。

I'm sorry I was at the Browns game, could have made your life easier sooner :) 对不起,我参加布朗队的比赛,本来可以使您的生活更轻松:)

listd = [lista, listb, listc]

if 'angle' in ''.join(lista) and ''.join(listb) and ''.join(listc):
    for idx, item, in enumerate(lista):
        for x, i in enumerate(listc):
            if 'angle' in item and 'angle' in i:
                if item.split()[1] != i.split()[1]:
                    listc[x] = i.split()[0] + ' ' + str(int(i.split()[1]) - 90)

print(listd)
 [['angle 45', 'color red', 'inside t'], ['angle 135', 'color blue', 'inside f'], ['above r', 'angle 225', 'color pink', 'inside o']] 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM