I'm trying to cross check two nested list values, and if I get a match, append the values from list1 into list2.
For example;
list1 = [[ip, hostname], [ip, hostname], [ip, hostname]]
list2 = [[ip, ip_upper, type, hostname, location], [ip, ip_upper, type, hostname, location], [ip, ip_upper, type, hostname, location]]
I want to check if the value in list1[x][0] is in list2, if so, replace the value of List2[x][3] with List1[x][1].
What I'm attempting is;
count = 0;
for row in list2:
if row[0] in hosts[count][0]:
new_hostname = hosts[count][1]
row[4].append(new_hostname)
count += 1
else:
continue
count += 1
I know the above is incorrect, i'm struggling to figure out how to access the values list1 whilst traversing list2. The reason is because I need to check each row, and then the value with the row and then amend specific values within the row.
Thanks for the RAPID response!
I've tried to implement the code given but am running into trouble when trying to create a diction from my list:
wow, you guys!
def doStuff(list1, list2):
mydic = dict(list2)
for l in list1:
l[3] = mydic.get(l[0], l[3])
return mydic
new_dic = doStuff(hostname, old_rows)
I'm receiving the error;
mydic = dict(list2)
ValueError: dictionary update sequence element #0 has length 6; 2 is required
Any ideas?
This works fine i guess, and its time complexity is only O(n + m) with n and m being the length of each list.
def doStuff(list1, list2):
mydic = dict(list1)
for l in list2:
l[3] = mydic.get(l[0], l[3])
Assuming the ip field value supports equality comparison (==), this solution may help you. It's quite plain and lame and probably not very optimised, but it works.
Note: it works for every occurrence of each element of list1 in list2, so if you had multiple matches in list2, they would all get updated.
list1 = [['1.2.3.4', 'ciao.com'],
['1.2.3.5', 'prova.net'],
['1.2.2.2', 'uovo.net']]
list2 = [['1.2.3.4', '1.2.3.x', 'type', 'xyz.com', 'puglia'],
['1.2.3.7', '1.2.3.x', 'type', 'zyx.com', 'lazio'],
['1.2.3.5', '1.2.3.x', 'type', 'yxz.com', 'molise']]
print list1
print list2
for i in list1:
ip = i[0]
for j in list2:
cur_ip = j[0]
if ip == cur_ip:
j[3] = i[1]
print list2
outputs:
[['1.2.3.4', 'ciao.com'], ['1.2.3.5', 'prova.net'], ['1.2.2.2', 'uovo.net']]
[['1.2.3.4', '1.2.3.x', 'type', 'xyz.com', 'puglia'], ['1.2.3.7', '1.2.3.x', 'type', 'zyx.com', 'lazio'], ['1.2.3.5', '1.2.3.x', 'type', 'yxz.com', 'molise']]
[['1.2.3.4', '1.2.3.x', 'type', 'ciao.com', 'puglia'], ['1.2.3.7', '1.2.3.x', 'type', 'zyx.com', 'lazio'], ['1.2.3.5', '1.2.3.x', 'type', 'prova.net', 'molise']]
Sort the target list on ip then use itertools.groupby to iterate over the targets. It may have a slight advantage if there are a lot of items in list2 that don't need to be modified (they are skipped).
import operator, itertools
ip = operator.itemgetter(0)
keys = dict(list1)
list2.sort(key = ip)
for key, group in itertools.groupby(list2, ip):
if key in keys:
for item in group:
item[3] = keys[key]
Related
I am trying to understand how to iterate through two lists look for words that begin with a specific letter and append them to a new list. I was thinking of using for loop and a nested for loop but my code is not working.
list1 = ['iPad','iPhone','macbook','screen','bottel cap','paper','keyboard', 'mouse','bat','Baseball']
list2 = ['couch','tv','remote control', 'play station', 'chair', 'blanket', 'table', 'mug']
list_letter_b = []
for item in list1:
if item[0] == "b":
list_letter_b.append(item)
for item in list2:
if item[0] == "b":
list_letter_b.append(item)
print("Here is your new list with only items starting with letter b or B {} ".format(list_letter_b))
This code works but it seems too long there has to be a way of making it simpler. Also, I would love to take values that are b and B but cant seems to make it happen.
Any advice is greatly appreciated.
Thank you
I mean, given the context, yours seems fine; however, if you simply want a smaller code footprint, you can do:
list1 = ['iPad','iPhone','macbook','screen','bottel cap','paper','keyboard', 'mouse','bat','Baseball']
list2 = ['couch','tv','remote control', 'play station', 'chair', 'blanket', 'table', 'mug']
list_letter_b = [item for item in list1 + list2 if item.lower().startswith("b")]
Note: this is not more "efficient" in any way, just a one line way of doing what you're doing.
Since u also want the values that have an uppercase 'B', you can call .lower() function on the item in the if condition if item[0].lower() == "b":
list1 = ['iPad','iPhone','macbook','screen','bottel cap','paper','keyboard', 'mouse','bat','Baseball']
list2 = ['couch','tv','remote control', 'play station', 'chair', 'blanket', 'table', 'mug']
list_letter_b = []
for item in list1 + list2:
if item[0].lower() == "b":
list_letter_b.append(item)
print("Here is your new list with only items starting with letter b or B {} ".format(list_letter_b))
Earlier post does help the OP code to be very compact, here is another way - just for simplifying a little, but following OP's orig. logic:
list_letter_b = []
for x in (list1 + list2): # process them as ONE unit/list
if x.lower().startswith('b'):
list_letter_b.append(x)
print("starting with letter b or B {} ".format(list_letter_b))
Output:
starting with letter b or B ['bottel cap', 'bat', 'Baseball', 'blanket']
Or 2nd way to use zip_longest from itertools:
it's because two lists have different size.
from itertools import zip_longest
list_letter_b = []
for x, y in zip_longest(list1, list2, fillvalue=''):
if x.lower().startswith('b'):
list_letter_b.append(x)
if y.lower().startswith('b'):
list_letter_b.append(y)
If I have two separated lists:
list1 = [['2021-05-24', '31220'],....., ['2021-05-24', '6640'],['2021-05-10', '8830'].....]
list2 = [['2021-05-24', '77860'],.....,['2021-05-24', '438000'],['2021-05-10', '9990'].....]
How could I combine them to
[['2021-05-24', 'add all numbers in '2021-05-24' together'],['2021-05-10', 'add all numbers in '2021-05-10' together']]
, '.....' means there are many list-tuples
I am considering delete the duplicated date in each list and then add two lists up:
import networkx as nx
G = nx.Graph()
G.add_nodes_from(sum(list2, []))
q = [[(s[i],s[i+1]) for i in range(len(s)-1)] for s in list2]
for i in q:
G.add_edges_from(i)
print([list(i) for i in nx.connected_components(G)])
but my code not only deleted the same dates but also deleted the same numbers.
Thanks in advance.
I'd recommend using a defaultdict:
from collections import defaultdict
result = defaultdict(int)
for k,v in (list1 + list2):
result[k] += v
Then you can convert the dict back to a list. Of course if you have several lists you may want to use itertools.chain instead of list1 + list2
You can go with creating new dictionary and do calculation and then create list out of it. Here is the code for that
result={}
for i in list1+list2: #creating dict and doing calculation
if i[0] in result.keys():
result[i[0]] += int(i[1])
else:
result[i[0]] = int(i[1])
result_list = [[key, result[key]] for key in result] #converting dict to expected list
print(result_list)
I have a single list that could be any amount of elements.
['jeff','ham','boat','','my','name','hello']
How do I split this one list into two lists or any amount of lists depending on blank string elements?
All these lists can then be put into one list of lists.
If you are certain that there is only one blank string in the list, you can use str.index to find the index of the blank string, and then slice the list accordingly:
index = lst.index('')
[lst[:index], lst[index + 1:]]
If there could be more than one blank string in the list, you can use itertools.groupby like this:
lst = ['jeff','ham','boat','','my','name','hello','','hello','world']
from itertools import groupby
print([list(g) for k, g in groupby(lst, key=bool) if k])
This outputs:
[['jeff', 'ham', 'boat'], ['my', 'name', 'hello'], ['hello', 'world']]
Using itertools.groupby, you can do:
from itertools import groupby
lst = ['jeff','ham','boat','','my','name','hello']
[list(g) for k, g in groupby(lst, key=bool) if k]
# [['jeff', 'ham', 'boat'], ['my', 'name', 'hello']]
Using bool as grouping key function makes use of the fact that the empty string is the only non-truthy string.
This is one approach using a simple iteration.
Ex:
myList = ['jeff','ham','boat','','my','name','hello']
result = [[]]
for i in myList:
if not i:
result.append([])
else:
result[-1].append(i)
print(result)
Output:
[['jeff', 'ham', 'boat'], ['my', 'name', 'hello']]
Let list_string be your list. This should do the trick :
list_of_list=[[]]
for i in list_string:
if len(i)>0:
list_of_list[-1].append(i)
else:
list_of_list.append([])
Basically, you create a list of list, and you go through your original list of string, each time you encounter a word, you put it in the last list of your list of list, and each time you encounter '' , you create a new list in your list of list. The output for your example would be :
[['jeff','ham','boat'],['my','name','hello']]
i'm not sure that this is what you're trying to do, but try :
my_list = ['jeff','ham','boat','','my','name','','hello']
list_tmp = list(my_list)
final_list = []
while '' in list_tmp:
idx = list_tmp.index('')
final_list.append(list_tmp[:idx])
list_tmp = list_tmp[idx + 1:]
I want make script that reads lines from file, than takes slices from each line, combines all slices from 1 line with all slices from 2 line, then combines all slices from previous step with 3rd line.
For example, we have
Stackoverflow (4)
python (3)
question (3)
I get first list with slices of (number) letters.
lst = ['Stac', 'tack', 'acko', 'ckov', 'kove', 'over', 'verf', 'erfl', 'rflo', 'flow']
Then i need to combine it with second list:
lst = ['pyt', 'yth', 'tho', 'hon']
Desired output:
finallist = ['Stacpyt', 'tackpyt', 'ackopyt', 'ckovpyt', 'kovepyt', 'overpyt', 'verfpyt', 'erflpyt', 'rflopyt', 'flowpyt' 'Stacyth', 'tackyth', 'ackoyth', 'ckovyth', 'koveyth', 'overyth', 'verfyth', 'erflyth', 'rfloyth', 'flowyth', ..... , 'erflhon', 'rflohon', 'flowhon']
then with 3rd list:
lst = ['que', 'ues', 'est', 'sti', 'tio', 'ion']
finallist = ['Stacpytque', 'tackpytque', 'ackopytque', 'ckovpytque', 'kovepytque', 'overpytque', 'verfpytque', 'erflpytque', 'rflopytque', .... 'erflhonion', 'rflohonion', 'flowhonion']
I stuck at point where I need to make finallist with combined results.
I am trying pieces of code like this, but its wrong:
for i in lst:
for y in finallist:
finallist.append(i + y)
So if finallist is empty - it should copy lst in first loop iteration, and if finallist is not empty it should combine each element with lst and so on.
I used re.match() in order to get the word and the integer value from your file.
Then, I compute all the sliced subwords and add them to a list, which is then added to a global list.
Finally, I compute all the possibilties you are looking for thank to itertools.product() which behaves like a nested for-loop.
Then, .join() the tuples obtained and you get the final list you wanted.
from itertools import product
from re import match
the_lists = []
with open("filename.txt", "r") as file:
for line in file:
m = match(r'(.*) \((\d+)\)', line)
word = m.group(1)
num = int(m.group(2))
the_list = [word[i:i+num] for i in range(len(word) - num + 1)]
the_lists.append(the_list)
combinaisons = product(*the_lists)
final_list = ["".join(c) for c in combinaisons]
Use ittertools
import itertools
list1 = ['Stac', 'tack', 'acko', 'ckov', 'kove', 'over', 'verf', 'erfl', 'rflo', 'flow']
list2 = ['pyt', 'yth', 'tho', 'hon']
list3 = ['que', 'ues', 'est', 'sti', 'tio', 'ion']
final_list = list(itertools.product(list(itertools.product(list1,list2)),list3))
This will give you all combinations, then you can just join all of them to get your string.
import itertools
def combine(lst):
result = list(itertools.product(*lst))
result = [''.join(item) for item in result]
return result
list1 = ['Stac', 'tack', 'acko', 'ckov', 'kove', 'over', 'verf', 'erfl', 'rflo', 'flow']
list2 = ['pyt', 'yth', 'tho', 'hon']
list3 = ['que', 'ues', 'est', 'sti', 'tio', 'ion']
lst = [list1, list2, list3] # append more list to lst, then pass lst to combination
print combine(lst)
Append all of the candidate lists to lst, and the combine() function will generate all kinds of combinations and then returns the result as a list.
I've got an arduino sending me serial data which is transposed into a dictionary.
However, not all entries have a value due data being sent at random.
Before sending the dictionary data to a CSV file I want to prune the empty values or values that are 0 from the dict.
Incoming data would look like this: (values only)
['','7','','49,'','173','158']
I want that to become
['7','49','173','158].
The script I currently use:
import serial
import time
def delete_Blanks(arrayName):
tempArray = array.copy()
for key, value in sorted(tempArray.items()):
if value == "":
del tempArray[key]
else:
print "Value is not nil"
return tempArray
array = {}
ser = serial.Serial('COM2', 9600, timeout=1)
key = 0
while 1:
length = len(array)
if len(array) in range(0,5):
array.update({key:ser.read(1000)})
key = key + 1
print "key is ", key
print array.values()
length = len(array)
else:
newArray = delete_Blanks(array)
print newArray.items()
break
from itertools import compress
l = ['','7','','49','','173','158']
ret = compress(l, map(lambda x: bool(x), l))
print(list(ret))
will output:
['7', '49', '173', '158']
if you have long arrays of data - it's better to work with iterators to avoid memory leaks. If you work with short lists - list comprehension is just fine
You can use a dictionary comprehension. This will remove all false values from a dictionary d:
d={key,d[key] for key in d if d[key]}
If it's just a plain list you can do something like this
Mylist = filter(None, Mylist)
Before creating the dictionary you can filter the two list, the list containing the keys and the list containing the values. Assuming both list are the same length you can then
mydict = dict(zip(l1, l2))
to create your new list
>>> li = ['','7','','49','','173','158']
>>> [e for e in li if e]
['7', '49', '173', '158']