Reputation: 763
I'm trying to come up with something to find the substring 'angle' in each of these lists of strings:
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
2) And if listA's 'angle' value does not equal listC's angle value,
Then get listC's angle value, subtract 90 and put the new string back in the list. So, listC would now look like:
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. 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. 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. 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)
Upvotes: 0
Views: 516
Reputation: 7952
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.
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).
Upvotes: 1
Reputation: 4606
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']]
Upvotes: 1
Reputation: 5658
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']
Upvotes: 1
Reputation: 1711
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.
I also created an empty list called results to store the matches and their values.
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).
So, we check all of the lists for the keyword and append()
the match to 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
Upvotes: 2
Reputation: 1155
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
Upvotes: 3