How to extend a list by overwriting the common values - python

list1=[{"status":1, "s_count":100}, {"status":2, "s_count":20}]
list2=[{"status":1, "s_count":0}, {"status":3, "s_count":30}]
list1.extend(list2) gives
[{"status":1, "s_count":100}, {"status":2, "s_count":20}, {"status":1,
"s_count":0}, {"status":3, "s_count":30}]
what I want is,
[{"status":1, "s_count":0}, {"status":2, "s_count":20}, {"status":3, "s_count":30}]

1) Consider using a dictionary instead of a list.
2) If you insist on using a list:
helper = []
for i in range(0,len(list1)):
for item in list2:
if item['status'] == list1[i]['status']:
list1[i]['s_count'] = item['s_count']
helper.add(item)
for item in helper:
list2.remove(item)
list1.extend(list2)
This is inefficient, so try to do 1 if possible.

Related

combine two strings in python

I have a list1 like this,
list1 = [('my', '1.2.3', 2),('name', '9.8.7', 3)]
I want to get a new list2 like this (joining first element with second element's second entry);
list2 = [('my2', 2),('name8', 3)]
As a first step, I am checking to join the first two elements in the tuple as follow,
for i,j,k in list1:
#print(i,j,k)
x = j.split('.')[1]
y = str(i).join(x)
print(y)
but I get this
2
8
I was expecting this;
my2
name8
what I am doing wrong? Is there any good way to do this? a simple way..
try
y = str(i) + str(x)
it should works.
The str(i).join(x), means that you see x as an iterable of strings (a string is an iterable of strings), and you are going to construct a string by adding i in between the elements of x.
You probably want to print('{}{}'.format(i+x)) however:
for i,j,k in list1:
x = j.split('.')[1]
print('{}{}'.format(i+x))
Try this:
for x in list1:
print(x[0] + x[1][2])
or
for x in list1:
print(x[0] + x[1].split('.')[1])
output
# my2
# name8
You should be able to achieve this via f strings and list comprehension, though it'll be pretty rigid.
list_1 = [('my', '1.2.3', 2),('name', '9.8.7', 3)]
# for item in list_1
# create tuple of (item[0], item[1].split('.')[1], item[2])
# append to a new list
list_2 = [(f"{item[0]}{item[1].split('.')[1]}", f"{item[2]}") for item in list_1]
print(list_2)
List comprehensions (and dict comprehensions) are some of my favorite things about python3
https://www.pythonforbeginners.com/basics/list-comprehensions-in-python
https://www.digitalocean.com/community/tutorials/understanding-list-comprehensions-in-python-3
Going with the author's theme,
list1 = [('my', '1.2.3', 2),('name', '9.8.7', 3)]
for i,j,k in list1:
extracted = j.split(".")
y = i+extracted[1] # specified the index here instead
print(y)
my2
name8
[Program finished]

Separate List data with Python

I have a list of multiple strings ) and I want to separate them by :
MainList :
[
GENERAL NOTES & MISCELLANEOUS DETAILS_None_None_None,
STR_XX_XX_0001,
STR_XX_XX_0002,
STR_XX_XX_0003,
GENERAL ARRANGEMENT_None_None_None,
STR_XX_XX_10001.0,
STR_XX_XX_10002.0,
STR_XX_XX_10003.0,
STR_XX_XX_10004.0,
STR_XX_XX_10005.0,
STR_XX_XX_10006.0
]
if string "_None_None_None" found in main list, it can add this data in new empty list and and remaining STR_XX_XX_0001 value to another list and it goes until it found another string with "_None_None_None" and do the same.
I have tried myself, But I think I won't be able to break my loop when it will find next string with "_None_None_None". Just figuring out the way, not sure logic is right.
empty1 = []
empty2 = []
for i in MainList:
if "_None_None_None" in i:
empty1.append(i)
# Need help on hear onwards
else:
while "_None" not in i:
empty2.append(i)
break
I am expecting the Output result in two list. Something like this:
List1:
[
GENERAL NOTES & MISCELLANEOUS DETAILS_None_None_None,
GENERAL ARRANGEMENT_None_None_None
]
List2:
[
[STR_XX_XX_0001,STR_XX_XX_0002,STR_XX_XX_0003],[STR_XX_XX_10001.0,STR_XX_XX_10002.0,STR_XX_XX_10003.0,STR_XX_XX_10004.0,STR_XX_XX_10005.0,STR_XX_XX_10006.0]
]
List2 is the list with sublists
You are making it a little too complicated, you can let the list run the whole way through without the internal while loop. Just make the decision for each element as it shows up in the loop:
empty1 = []
empty2 = []
for i in MainList:
if "_None_None_None" in i:
empty1.append(i)
else:
empty2.append(i)
This will give you two lists:
> empty1
> ['GENERAL NOTES & MISCELLANEOUS DETAILS_None_None_None',
'GENERAL ARRANGEMENT_None_None_None']
> empty2
> ['STR_XX_XX_0001',
'STR_XX_XX_0002',
'STR_XX_XX_0003',
'STR_XX_XX_10001.0',
'STR_XX_XX_10002.0',
'STR_XX_XX_10003.0',
'STR_XX_XX_10004.0',
'STR_XX_XX_10005.0',
'STR_XX_XX_10006.0']
EDIT Based on comment
If the commenter is correct and you want to group the non-NONE values into separate lists, this is a good use case for itertools.groupby. It will make the groups for you in a convenient, efficient way and your loop will look almost the same:
from itertools import groupby
empty1 = []
empty2 = []
for k, i in groupby(MainList, key = lambda x: "_None_None_None" in x):
if k:
empty1.extend(i)
else:
empty2.append(list(i))
This will give you the same empty1 but empty2 will not be a list of lists:
[['STR_XX_XX_0001', 'STR_XX_XX_0002', 'STR_XX_XX_0003'],
['STR_XX_XX_10001.0',
'STR_XX_XX_10002.0',
'STR_XX_XX_10003.0',
'STR_XX_XX_10004.0',
'STR_XX_XX_10005.0',
'STR_XX_XX_10006.0']]
You can try the following code snippet:
dlist = ["GENERAL NOTES & MISCELLANEOUS DETAILS_None_None_None","STR_XX_XX_0001","STR_XX_XX_0002","STR_XX_XX_0003", "GENERAL ARRANGEMENT_None_None_None","STR_XX_XX_10001.0","STR_XX_XX_10002.0", "STR_XX_XX_10003.0", "STR_XX_XX_10004.0", "STR_XX_XX_10005.0", "STR_XX_XX_10006.0"]
with_None = [elem for elem in dlist if elem.endswith("_None")]
without_None = [elem for elem in dlist if not elem.endswith("_None")]
You can also write a generic function for the process:
def cust_sept(src_list, value_to_find,f):
with_value, without_value = [elem for elem in dlist if f(elem,value_to_find)],[elem for elem in dlist if not f(elem,value_to_find)]
return with_value,without_value
list_one,list_two = cust_sept(dlist,"_None",str.endswith)

Group elements of a list based on repetition of values

I am really new to Python and I am having a issue figuring out the problem below.
I have a list like:
my_list = ['testOne:100', 'testTwo:88', 'testThree:76', 'testOne:78', 'testTwo:88', 'testOne:73', 'testTwo:66', 'testThree:90']
And I want to group the elements based on the occurrence of elements that start with 'testOne'.
Expected Result:
new_list=[['testOne:100', 'testTwo:88', 'testThree:76'], ['testOne:78', 'testTwo:88'], ['testOne:73', 'testTwo:66', 'testThree:90']]
Just start a new list at every testOne.
>>> new_list = []
>>> for item in my_list:
if item.startswith('testOne:'):
new_list.append([])
new_list[-1].append(item)
>>> new_list
[['testOne:100', 'testTwo:88', 'testThree:76'], ['testOne:78', 'testTwo:88'], ['testOne:73', 'testTwo:66', 'testThree:90']]
Not a cool one-liner, but this works also with more general labels:
result = [[]]
seen = set()
for entry in my_list:
test, val = entry.split(":")
if test in seen:
result.append([entry])
seen = {test}
else:
result[-1].append(entry)
seen.add(test)
Here, we are keeping track of the test labels we've already seen in a set and starting a new list whenever we encounter a label we've already seen in the same list.
Alternatively, assuming the lists always start with testOne, you could just start a new list whenever the label is testOne:
result = []
for entry in my_list:
test, val = entry.split(":")
if test == "testOne":
result.append([entry])
else:
result[-1].append(entry)
It'd be nice to have an easy one liner, but I think it'd end up looking a bit too complicated if I tried that. Here's what I came up with:
# Create a list of the starting indices:
ind = [i for i, e in enumerate(my_list) if e.split(':')[0] == 'testOne']
# Create a list of slices using pairs of indices:
new_list = [my_list[i:j] for (i, j) in zip(ind, ind[1:] + [None])]
Not very sophisticated but it works:
my_list = ['testOne:100', 'testTwo:88', 'testThree:76', 'testOne:78', 'testTwo:88', 'testOne:73', 'testTwo:66', 'testThree:90']
splitting_word = 'testOne'
new_list = list()
partial_list = list()
for item in my_list:
if item.startswith(splitting_word) and partial_list:
new_list.append(partial_list)
partial_list = list()
partial_list.append(item)
new_list.append(partial_list)
joining the list into a string with delimiter |
step1="|".join(my_list)
splitting the listing based on 'testOne'
step2=step1.split("testOne")
appending "testOne" to the list elements to get the result
new_list=[[i for i in str('testOne'+i).split("|") if len(i)>0] for i in step2[1:]]

cycle "for" in Python

I have to create a three new lists of items using two different lists.
list_one = ['one', 'two','three', 'four','five']
list_two = ['blue', 'green', 'white']
So, len(list_one) != len(list_two)
Now I should create an algorithm(a cycle) which can do this:
[oneblue, twoblue, threeblue, fourblue, fiveblue]. Same for 'green' and 'white'.
I undestand that I should create three cycles but I don't know how.
I've tried to make a function like this but it doesn't works.
def mix():
i = 0
for i in range(len(list_one)):
new_list = list_one[i]+list_two[0]
i = i+1
return new_list
What am I doing wrong?
I think you might be looking for itertools.product:
>>> [b + a for a,b in itertools.product(list_two, list_one)]
['oneblue',
'twoblue',
'threeblue',
'fourblue',
'fiveblue',
'onegreen',
'twogreen',
'threegreen',
'fourgreen',
'fivegreen',
'onewhite',
'twowhite',
'threewhite',
'fourwhite',
'fivewhite']
You should do this
def cycle(list_one,list_two):
newList = []
for el1 in list_two:
for el2 in list_one:
newList.append(el2+el1)
return newList
There are a few problems with your code:
When you do a for loop for i in ...:, you do not need to initialize i (i = 0) and you should not increment it (i = i + 1) since Python knows that i will take all values specified in the for loop definition.
If your code indentation (indentation is very important in Python) is truly the one written above, your return statement is inside the for loop. As soon as your function encounters your return statement, your function will exit and return what you specified: in this case, a string.
new_list is not a list but a string.
In Python, you can loop directly over the list items as opposed to their index (for item in list_one: as opposed to for i in range(len(list_one)):
Here is your code cleaned up:
def mix():
new_list = []
for i in list_one:
new_list.append(list_one[i]+list_two[0])
return new_list
This can be rewritten using a list comprehension:
def mix(list_one, list_two):
return [item+list_two[0] for item in list_one]
And because list_two has more than one item, you would need to iterate over list_two as well:
def mix(list_one, list_two):
return [item+item2 for item in list_one for item2 in list_two]
return should be out of for loop.
No need to initialize i and increment it, since you are using range.
Also, since both list can be of variable length, don't use range. Iterate over the list elements directly.
def mix(): should be like def mix(l_one,l_two):
All above in below code:
def mix(l_one,l_two):
new_list = []
for x in l_one:
for y in l_two:
new_list.append(x+y)
return new_list
list_one = ['one', 'two','three', 'four','five']
list_two = ['blue', 'green', 'white']
n_list = mix(list_one,list_two)
print n_list
Output:
C:\Users\dinesh_pundkar\Desktop>python c.py
['oneblue', 'onegreen', 'onewhite', 'twoblue', 'twogreen', 'twowhite', 'threeblu
e', 'threegreen', 'threewhite', 'fourblue', 'fourgreen', 'fourwhite', 'fiveblue'
, 'fivegreen', 'fivewhite']
C:\Users\dinesh_pundkar\Desktop>
Using List Comprehension, mix() function will look like below:
def mix(l_one,l_two):
new_list =[x+y for x in l_one for y in l_two]
return new_list

Nested lists python

Can anyone tell me how can I call for indexes in a nested list?
Generally I just write:
for i in range (list)
but what if I have a list with nested lists as below:
Nlist = [[2,2,2],[3,3,3],[4,4,4]...]
and I want to go through the indexes of each one separately?
If you really need the indices you can just do what you said again for the inner list:
l = [[2,2,2],[3,3,3],[4,4,4]]
for index1 in xrange(len(l)):
for index2 in xrange(len(l[index1])):
print index1, index2, l[index1][index2]
But it is more pythonic to iterate through the list itself:
for inner_l in l:
for item in inner_l:
print item
If you really need the indices you can also use enumerate:
for index1, inner_l in enumerate(l):
for index2, item in enumerate(inner_l):
print index1, index2, item, l[index1][index2]
Try this setup:
a = [["a","b","c",],["d","e"],["f","g","h"]]
To print the 2nd element in the 1st list ("b"), use print a[0][1] - For the 2nd element in 3rd list ("g"): print a[2][1]
The first brackets reference which nested list you're accessing, the second pair references the item in that list.
You can do this. Adapt it to your situation:
for l in Nlist:
for item in l:
print item
The question title is too wide and the author's need is more specific. In my case, I needed to extract all elements from nested list like in the example below:
Example:
input -> [1,2,[3,4]]
output -> [1,2,3,4]
The code below gives me the result, but I would like to know if anyone can create a simpler answer:
def get_elements_from_nested_list(l, new_l):
if l is not None:
e = l[0]
if isinstance(e, list):
get_elements_from_nested_list(e, new_l)
else:
new_l.append(e)
if len(l) > 1:
return get_elements_from_nested_list(l[1:], new_l)
else:
return new_l
Call of the method
l = [1,2,[3,4]]
new_l = []
get_elements_from_nested_list(l, new_l)
n = [[1, 2, 3], [4, 5, 6, 7, 8, 9]]
def flatten(lists):
results = []
for numbers in lists:
for numbers2 in numbers:
results.append(numbers2)
return results
print flatten(n)
Output: n = [1,2,3,4,5,6,7,8,9]
I think you want to access list values and their indices simultaneously and separately:
l = [[2,2,2],[3,3,3],[4,4,4],[5,5,5]]
l_len = len(l)
l_item_len = len(l[0])
for i in range(l_len):
for j in range(l_item_len):
print(f'List[{i}][{j}] : {l[i][j]}' )

Categories

Resources