Modify a list using an integer - python

I am trying to figure out the following:
I take as input a list of lists and an integer N and the objective is to repeat the elements of the sublists N times by adding in front of each element a number in the range of N in increasing order.
For example as input we would receive:
>>> conversion([['GREEN', 'PURPLE'], ['RED']], 3)
[['GREEN0', 'GREEN1', 'GREEN2', 'PURPLE0', 'PURPLE1', 'PURPLE2'], ['RED0', 'RED1', 'RED2']]
My idea was creating an empty list, then adding each element of each sublist in this empty list. Then I would replace the elements with the same version and add range(N) at the end of it but in writing the code I either cannot separate the elements of sublists in the new list or cannot add or separate the different copies of the elements and the values in range(N)
I hope my explanation was clear and thank you for any help possible.

Your idea of a new list is correct. Here is one possible solution.
def conversion(l, n):
new_list = []
for inner_list in l:
new_list.append([])
for word in inner_list:
for i in range(n):
new_list[-1].append(word + str(i))
return new_list
One-liner alternative. (Just for fun):
def conversion(l, n):
return [[word + str(i) for word in inner_list for i in range(n)] for inner_list in l ]

def conversion(input_list, count):
output_list = [
[
input_list[k][j] + str(i)
for j in range(len(input_list[k]))
for i in range(count)
]
for k in range(len(input_list))
]
return output_list

It may be useful to separate the two tasks into smaller functions to make it easier to understand. use listrepeater() to achieve the desired outcome of a list, and then run it in nestedListRepeater()
def listrepeater(l,multiplier):
output = []
for val in l:
for i in range(multiplier):
output.append(val + str(i))
i+=1
return output
def nestedListRepeater(inputlist,multiplier):
outputlist = []
for sublist in inputlist:
outputlist.append(listrepeater(sublist,multiplier))
return outputlist
nestedListRepeater([['GREEN', 'PURPLE'], ['RED']],3)

Related

Unpack List with key value pair

I need to get the value(the right hand value after the colon) in this list
list = [apple:tuesday, banana:wednesday, guava:thursday]
first your list will be like
list1=["apple:tuesday", "banana:wednesday", "guava:thursday"]
k=0
for i in list1:
x=i.split(":")
print(x)
list1[k]=x[1]
k+=1
print(list1)
i hope this is what you were trying to do
you can do this by list comprehension.it's easy and fast
l = ["apple:tuesday", "banana:wednesday", "guava:thursday"]
new_l = [item.split(":")[1] for item in l]
list comprehension work like this
l = [i for i in range(5)]
# l = [0,1,2,3,4]

how to transform a python list to a list of tuple in 1/2 lines?

Input: ['a','b','c','d','e']
Output: [('a','b'),('c','d'),('e')]
How can I do it in 1 or 2 lines of code ?
For the moment I have this:
def tuple_list(_list):
final_list = []
temp = []
for idx, bat in enumerate(_list):
temp.append(bat)
if idx%2 == 1:
final_list.append(temp)
temp = []
if len(temp) > 0: final_list.append(temp)
return final_list
tuple_list(['a','b','c','d','e'])
You can use list comprehension. First we will have a range with a step of 2. Using this we will take proper slices from the input list to get the desired result:
lst = ['a','b','c','d','e']
result = [tuple(lst[i:i+2]) for i in range(0, len(lst), 2)]
Try this list comprehension
x = ['a','b','c','d','e']
[(x[i],x[i+1]) for i in range(0,len(x)-1) if i%2==0]
You could create an iterator with the built in iter() function and pass that to the built zip() function.
l = ['a','b','c','d','e']
i = iter(l)
zip(i, i)
if you'd like to group by 3 you can pass it 3 times to zip()
zip(i, i, i)
x = ['a','b','c','d','e']
y = [tuple(x[i:i+2]) for i in range(0,len(x),2)]
You can slice the array by moving a sliding window of size 2 over your list.
range(start, end, step) helps you to move window by step(2 in your case) while slicing helps you create smaller list out of bigger list.
All that put into a list comprehension gives you a desired output.

How to extract the first element (as a list of string) of the n-th elements of a nested list, Python

I am a fresh python beginner and trying to extract the first element of the first n-th elements of a nested list. But it doesn't work so far.
Say:
list = [["Anna","w",15],["Peter","m",20],["Zani","m",10], ["Lily","w",19]]
Goal:
list_new = ['Anna','Peter','Zani'...(#until the n-th elements)]
If I want to first element of all the elements in the list, it should be:
for i in list:
for j in i:
print j[0]
But what if i only want to strip the first element of the n-th elements of the list, instead of all the elements.
For example for the first 2 elements:
I tried:
for i in list[0:2]:
for j in i:
print j[0]
but it didn't work.
What's more, if i want to give the value of n later by using
def sheet(list, n)
and the return statement, how could i do it?
Thank you very much!!
lst = [["Anna","w",15],["Peter","m",20],["Zani","m",10], ["Lily","w",19]]
n = 2
print(lst[n][0])
Output:
Zani
---Updated answer for the details added in the question---
l = [["Anna","w",15],["Peter","m",20],["Zani","m",10], ["Lily","w",19]]
n = 2
for i in range(n):
print(l[i][0])
Output:
Anna
Peter
You can use a list comprehension. Given an input list of lists L:
L_new = [i[0] for i in L[:n]]
Functionally, you can use operator.itemgetter. In addition, you can use itertools.islice to avoid creating an intermediary list:
from operator import itemgetter
from itertools import islice
L_new = list(map(itemgetter(0), islice(L, 0, n)))
Be careful, list is reserved for the built-in function list() in python, you should not use 'list' as variable name.
To get the first element of each nested list :
l = [["Anna","w",15],["Peter","m",20],["Zani","m",10], ["Lily","w",19]]
for e in l:
print(e[0])
Prints :
Anna
Peter
Zani
Lily
To do the same on the nth first elements :
def sheet(l, n):
return [e[0] for e in l[:n]]
sheet(l, 3)
Returns
['Anna', 'Peter', 'Zani']
EDIT
def sheet(l, n):
for e in l[:n]
return [e[0]]
This code only returns ['Anna'] because the return statement stops the function. The for loop is stopped at the first element.
def sheet(l, n):
return [e[0] for e in l[:n]]
is equivalent to :
def sheet(l, n):
result = [e[0] for e in l[:n]]
return result
which is equivalent to :
def sheet(l, n):
result = []
for e in l[:n]:
result.append(e[0])
return result
The for loop can ends before the return statement.
More informations here.
Just try this one which will be easier for you to understand:
n = int(input())
lst = [["Anna","w",15],["Peter","m",20],["Zani","m",10], ["Lily","w",19]]
lst_new = []
for item in lst[:n]:
name, *rest = item
lst_new.append(name)

Python unflatten list based on second list

I have 2 Python lists:
list_a = [[['Ab'], ['Qr', 'Zr']], [['Gt', 'Mh', 'Nt'], ['Dv', 'Cb']]]
list_b = [['Ab', 'QrB', 'Zr'], ['GtB', 'MhB', 'Nt6B', 'DvB', 'Cb6B5']]
I need to un-flatten list_b based on list_a. I need:
list_c = [['Ab'], ['QrB', 'Zr'], [['GtB', 'MhB', 'Nt6B'], ['DbB', 'Cb6B5']]]
Is there a way to get this list_c?
Additional Information:
The lists will always be defined such that:
A partial string from list_a will always be found in list_b. eg. for Gt in one list, there will be either Gt or GtB in the 2nd list.
Entries in each list cannot be in a different order - i.e. if Qr comes before Zr in one list then it (Qr or QrB) must come before Zr in the 2nd list.
Each list can have a maximum of 20 strings in it.
Each list has only unique strings.. eg. Gt cannot occur 2 or more times in any list.
Attempt:
Here is what I have tried:
list_c = [[],[]]
for ty,iten in enumerate(list_b):
for q in iten:
for l_e in list_a:
for items in l_e:
for t,qr in enumerate(items):
if qr in q:
list_c[ty].append([q])
the output of this is:
[[['Ab'], ['QrB'], ['Zr']], [['GtB'], ['MhB'], ['Nt6B'], ['DbB'], ['Cb6B5']]]
The problem is that ['QrB'], ['Zr'] should be combined ['QrB','Zr'] just like they are combined in list_a.
Attempt 2:
for ty,iten in enumerate(list_b):
for q in iten:
for l_e,m in enumerate(list_a):
for ss,items in enumerate(m):
for t,qr in enumerate(items):
if qr in q:
list_a[l_e][ss][t] = q
This works and produces the required output:
[[['Ab'], ['QrB', 'Zr']], [['GtB', 'MhB', 'Nt6B'], ['DvB', 'Cb6B5']]]
However, it (attempt 2) is too long and I would like to know: it does not seem that this is the proper way to do this in Python. Is there is a more Pythonic way to do this?
If all you care about is the length of the sublists in list_a then can transform list_a into its sublist lengths and then use that to slice the sublists of list_b:
# Transform list_a into len of sublists, (generator of generators :)
index_a = ((len(l2) for l2 in l1) for l1 in list_a))
list_c = []
for flatb, index in zip(list_b, index_a):
splitb = []
s = 0
for i in index:
splitb.append(flatb[s:s+i])
s += i
list_c.append(splitb)
Value of list_c:
[[['Ab'], ['QrB', 'Zr']], [['GtB', 'MhB', 'Nt6B'], ['DvB', 'Cb6B5']]]
This is a recursive variant for arbitrary depth of nesting. Not too pretty, but should work.
list_a = [[['Ab'], ['Qr', 'Zr']], [['Gt', 'Mh', 'Nt'], ['Dv', 'Cb']]]
list_b = [['Ab', 'QrB', 'Zr'], ['GtB', 'MhB', 'Nt6B', 'DvB', 'Cb6B5']]
def flatten(l):
for el in l:
if isinstance(el, list):
for sub in flatten(el):
yield sub
else:
yield el
def flitten(l1, l2, i):
result = []
for j in l1:
if isinstance(j, list):
i, res = flitten(j, l2, i)
result.append(res)
else:
result.append(l2[i])
i += 1
return i, result
def flutten(l1, l2):
i, result = flitten(l1, list(flatten(l2)), 0)
return result
print(flutten(list_a, list_b))
# prints [[['Ab'], ['QrB', 'Zr']], [['GtB', 'MhB', 'Nt6B'], ['DvB', 'Cb6B5']]]
Your code does not look too long given the fairly complicated nature of the task (find a list within a list within a list and match it to a list within another list according to the first two letters, and replace the original value with the matched value retaining the nested structure of the original list...)
You could at least eliminate one of the loops like this:
for sub_a, sub_b in zip(list_a, list_b):
for inner_a in sub_a:
for i, a in enumerate(inner_a):
for b in sub_b:
if b.startswith(a):
inner_a[i] = b
If you want a more general solution it will probably involve recursion as in #Tibor's answer.
EDIT: Given the extra information you have supplied, you could recursively work through list_a, replacing all the short strings with their full versions from an iterator based on the flattened version of list_b. This uses the fact that the strings appear in the same order in both lists with no duplicates.
def replace_abbreviations(L, full_names):
for i, item in enumerate(L):
if isinstance(item, basestring):
L[i] = full_names.next()
elif isinstance(item, list):
replace_abbreviations(item, full_names)
replace_abbreviations(list_a, (item for L in list_b for item in L))
Alternatively you can get a flattened list of the indices of each string in both lists and then loop through those:
def flat_indices(L):
for i, item in enumerate(L):
if isinstance(item, list):
for j, inner_list in flat_indices(item):
yield (j, inner_list)
else:
yield (i, L)
for (a, i), (b, j) in zip(flat_indices(list_a), flat_indices(list_b)):
a[i] = b[j]

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