Python trouble with matching tuples - python

For reference this is my code:
list1 = [('10.180.13.101', '10.50.60.30', 'STCMGMTUNIX01')]
list2 = [('0.0.0.0', 'STCMGMTUNIX01')]
for i in list1:
for j in list2:
for k in j:
print (k)
if k.upper() in i:
matching_app.add(j)
for i in matching_app:
print (i)
When I run it, it does not match. This list can contain two or three variables and I need it to add it to the matching_app set if ANY value from list2 = ANY value from list1. It does not work unless the tuples are of equal length.
Any direction to how to resolve this logic error will be appreciated.

You can solve this in a few different ways. Here are two approaches:
Looping:
list1 = [('10.180.13.101', '10.50.60.30', 'STCMGMTUNIX01')]
list2 = [('0.0.0.0', 'STCMGMTUNIX01')]
matches = []
for i in list1[0]:
if i in list2[0]:
matches.append(i)
print(matches)
#['STCMGMTUNIX01']
List Comp with a set
merged = list(list1[0] + list2[0])
matches2 = set([i for i in merged if merged.count(i) > 1])
print(matches2)
#{'STCMGMTUNIX01'}

I'm not clear of what you want to do. You have two lists, each containing exactly one tuple. There also seems to be one missing comma in the first tuple.
For finding an item from a list in another list you can:
list1 = ['10.180.13.101', '10.50.60.30', 'STCMGMTUNIX01']
list2 = ['0.0.0.0', 'STCMGMTUNIX01']
for item in list2:
if item.upper() in list1: # Check if item is in list
print(item, 'found in', list1)
Works the same way with tuples.

Related

Easier way to check if an item from one list of tuples doesn't exist in another list of tuples in python

I have two lists of tuples, say,
list1 = [('item1',),('item2',),('item3',), ('item4',)] # Contains just one item per tuple
list2 = [('item1', 'd',),('item2', 'a',),('item3', 'f',)] # Contains multiple items per tuple
Expected output: 'item4' # Item that doesn't exist in list2
As shown in above example I want to check which item in tuples in list 1 does not exist in first index of tuples in list 2. What is the easiest way to do this without running two for loops?
Assuming your tuple structure is exactly as shown above, this would work:
tuple(set(x[0] for x in list1) - set(x[0] for x in list2))
or per #don't talk just code, better as set comprehensions:
tuple({x[0] for x in list1} - {x[0] for x in list2})
result:
('item4',)
This gives you {'item4'}:
next(zip(*list1)) - dict(list2).keys()
The next(zip(*list1)) gives you the tuple ('item1', 'item2', 'item3', 'item4').
The dict(list2).keys() gives you dict_keys(['item1', 'item2', 'item3']), which happily offers you set operations like that set difference.
Try it online!
This is the only way I can think of doing it, not sure if it helps though. I removed the commas in the items in list1 because I don't see why they are there and it affects the code.
list1 = [('item1'),('item2'),('item3'), ('item4')] # Contains just one item per tuple
list2 = [('item1', 'd',),('item2', 'a',),('item3', 'f',)] # Contains multiple items per tuple
not_in_tuple = []
OutputTuple = [(a) for a, b in list2]
for i in list1:
if i in OutputTuple:
pass
else:
not_in_tuple.append(i)
for i in not_in_tuple:
print(i)
You don't really have a choice but to loop over the two lists. Once efficient way could be to first construct a set of the first elements of list2:
items = {e[0] for e in list2}
list3 = list(filter(lambda x:x[0] not in items, list1))
Output:
>>> list3
[('item4',)]
Try set.difference:
>>> set(next(zip(*list1))).difference(dict(list2))
{'item4'}
>>>
Or even better:
>>> set(list1) ^ {x[:1] for x in list2}
{('item4',)}
>>>
that is a difference operation for sets:
set1 = set(j[0] for j in list1)
set2 = set(j[0] for j in list2)
result = set1.difference(set2)
output:
{'item4'}
for i in list1:
a=i[0]
for j in list2:
b=j[0]
if a==b:
break
else:
print(a)

Replace string in specific index in list of lists python

How can i replace a string in list of lists in python but i want to apply the changes only to the specific index and not affecting the other index, here some example:
mylist = [["test_one", "test_two"], ["test_one", "test_two"]]
i want to change the word "test" to "my" so the result would be only affecting the second index:
mylist = [["test_one", "my_two"], ["test_one", "my_two"]]
I can figure out how to change both of list but i can't figure out what I'm supposed to do if only change one specific index.
Use indexing:
newlist = []
for l in mylist:
l[1] = l[1].replace("test", "my")
newlist.append(l)
print(newlist)
Or oneliner if you always have two elements in the sublist:
newlist = [[i, j.replace("test", "my")] for i, j in mylist]
print(newlist)
Output:
[['test_one', 'my_two'], ['test_one', 'my_two']]
There is a way to do this on one line but it is not coming to me at the moment. Here is how to do it in two lines.
for two_word_list in mylist:
two_word_list[1] = two_word_list.replace("test", "my")

Loop through 2 list of dictionaries

I have this 2 list of dictionaries, I was trying to print out all the names from list1 if they are not found in list2.
list1=[{'name':'A','color':'1'},
{'name':'B','color':'2'}]
list2=[{'name':'A','color':'3'},
{'name':'C','color':'1'}]
for item in list1:
for ii in list2:
if item['name'] != ii['name']:
print item['name']
The output I'm getting is
A
B
B
I expected it to print B because there's not b in list2. Not sure what I'm doing wrong...any help would be appreciated.
Thanks
That's (obviously) not the logic of your code. You iterate through all combinations of names, and print the one from list1 every time it doesn't match any name in list2.
Instead, don't print it until you know it is a mismatch for all of those names:
for item in list1:
found = False
for ii in list2:
if item['name'] == ii['name']:
found = True
if not found:
print item['name']
This is the direct change to your implementation. There are one-liners that can do this using comprehensions, all, and other Python capabilities.
You iterate over and print in every cases where the match is not found.
You can instead use a lookup in a set which is more effective:
for x in list1:
if x['name'] not in {y['name'] for y in list2}:
print(x['name'])
Using all(), you can do:
for x in list1:
if all(x['name'] != y['name'] for y in list2):
print(x['name'])
Currently in your double for loop you print item['name'] for a mismatch between any two elements of list1 and list2, which is not what you want.
Instead you can convert the names in both lists to a set and take the set difference
list1=[{'name':'A','color':'1'},
{'name':'B','color':'2'}]
list2=[{'name':'A','color':'3'},
{'name':'C','color':'1'}]
#Iterate through both lists and convert the names to a set in both lists
set1 = {item['name'] for item in list1}
set2 = {item['name'] for item in list2}
#Take the set difference to find items in list1 not in list2
output = set1 - set2
print(output)
The output will be
{'B'}
If the names are unique in list1, you can use a set:
list1=[{'name':'A','color':'1'},
{'name':'B','color':'2'}]
list2=[{'name':'A','color':'3'},
{'name':'C','color':'1'}]
set1 = set(d['name'] for d in list1)
missingNames = set1.difference(d['name'] for d in list2) # {'B'}
If they are not unique and you want to match number of instances, you can do it with Counter from collections:
from collections import Counter
count1 = Counter(d['name'] for d in list1)
count2 = Counter(d['name'] for d in list2)
missingNames = list((count1-count2).elements()) # ['B']
With Counter, if you had two entries in list1 with name 'A', then the output would have been ['A','B'] since only one of the two 'A' in list1 would find a match in list2

Compare two list and output missing and extra element (Python)

I've 2 lists(sorted) of prefix and would like to compare it in Python so that I can output which element in the original list was missing and which was added.
Eg.
list1_original = ['1.1.1.1/24','2.2.2.2/24','3.3.3.3/24','4.4.4.4/24']
list2 = ['3.3.3.3/24','4.4.4.4/24','5.5.5.5/24','6.6.6.6/24']
I want to compare the 2 lists and output the add/remove element in list1_original. ie:
1.1.1.1/24, 2.2.2.2/24 = missing
5.5.5.5/24, 6.6.6.6/24 = added
If there is no duplicates in given lists you may use sets and their "-" operator:
list1 = ['1.1.1.1/24', '2.2.2.2/24', '3.3.3.3/24', '4.4.4.4/24']
list2 = ['3.3.3.3/24', '4.4.4.4/24', '5.5.5.5/24', '6.6.6.6/24']
set1 = set(list1)
set2 = set(list2)
missing = list(sorted(set1 - set2))
added = list(sorted(set2 - set1))
print('missing:', missing)
print('added:', added)
this prints
missing: ['1.1.1.1/24', '2.2.2.2/24']
added: ['5.5.5.5/24', '6.6.6.6/24']
With sets you can compare lists:
missing = set(list1_original).difference(list2)
added = set(list2).difference(list1_original)
Keep in mind that the output is a set. To cast the output into a list you can use list(missing).
You can get the result using a loop and some conditional statements.
list1 = ['1.1.1.1/24', '2.2.2.2/24', '3.3.3.3/24', '4.4.4.4/24']
list2 = ['3.3.3.3/24', '4.4.4.4/24', '5.5.5.5/24', '6.6.6.6/24']
for i in list1:
if i in list2:
print("added",i)
else:
print("missing",i)
missing 1.1.1.1/24
missing 2.2.2.2/24
added 3.3.3.3/24
added 4.4.4.4/24
Same thing can also be framed like so,
[print("added",i) if i in list2 else print("missing",i) for i in list1]
This will work regardless duplicate values without sorted().
>>> def finder(arr1,arr2):
for i in range(len(arr1)):
if arr1[i] not in arr2:
print("missing",arr1[i])
for j in range(len(arr2)):
if arr2[j] not in arr1:
print("added",arr2[j])

Python append adds an item to every variable

I'm iterating on a list and attempting to create sublists from its items. Every time I append to a variable, the value is added to every other variable that I have defined. I've stripped down the code substantially to illustrate.
item = 'things.separated.by.periods'.split('.')
list1 = list2 = []
i = item.pop(0)
print i
list1.append(i)
i = item.pop(0)
print i
list2.append(i)
print(item, list1, list2)
Returns:
things
separated
(['by', 'periods'], ['things', 'separated'], ['things', 'separated'])
What I expected:
things
separated
(['by', 'periods'], ['things'], ['separated'])
I think this might by answered here, but I'm not sure how to apply this fix to my circumstances. Thanks in advance!
The problem is the line
list1 = list2 = []
This makes list1 and list2 refer to the exact same list, so that if you append an item to one you also append it to the other. Change it to
list1 = []
list2 = []
list1 = list2 = []
You are setting list1 to be the exact same list as list2. Therefore, they basically mean the same thing.
To fix this, try something like this:
list1, list2 = [], []

Categories