How can I merge multiple unknown number of lists together? - python

Based on the number of time the for loop runs, I get multiple list. I want to merge all those list and make one list.
for example:
list = []
for i in item:
list.append(i)
print(list)
How can I merge all the list I get to one list ?

If your item is list of lists, then you can use extend to achieve the same.
lst = []
for i in item:
lst.append(i)
out = []
for sublist in lst:
out.extend(sublist)
print(out)
Also, avoid using python keywords like list for the variable name, use something like lst instead.

You should avoid using list as a variable name, it's a reserved word for python lists.
This code should work for you:
list_ = []
f_list = []
item = [1,2,3,4,5]
for i in item:
list_.append(i)
f_list.extend(list_)
print(list_)
print("Final list - ", f_list)
Output:
[1]
[1, 2]
[1, 2, 3]
[1, 2, 3, 4]
[1, 2, 3, 4, 5]
Final list - [1, 1, 2, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4, 5]

Related

Python: how to remove single quote on first and last element of list

i have a list that goes like this ['1,2'] and i need to turn it into [1, 2]. Using int() won't work. Is there a way to add a single quote and then use int(), a way to remove a single quote or is there just a better way to do this?
here is the code that i am using
a_list = genres_selected.split()
map_object = map(int, a_list)
genres_selected_use = list(map_object)
genres_selected will always be different as it is being passed through ajax form
but here it is "1, 2"
I think you are looking to remove the string and convert it into an integer. Since the list has a string, you want to split the string using comma delimiter.
list_vals = ['1,2,3,4,5,6']
map_object = map(int, list_vals[0].split(','))
print (list(map_object))
The output of this will be:
[1, 2, 3, 4, 5, 6]
However, if your list has multiple strings of integers in single quotes, you can do:
my_list = ['1,2','3,4','5,6']
num_list = [[int(i) for i in num.split(',')] for num in my_list]
print (num_list)
The output of this will be:
[[1, 2], [3, 4], [5, 6]]
lst = ['1,2', '3,4,5']
new_list = []
for item in lst:
new_list.extend([int(num) for num in item.strip().split(',')])
print(new_list)
>>> [1, 2, 3, 4, 5]
One Liner Version
lst = ['1,2', '3,4,5']
print([int(item) for sublist in map(lambda item: item.split(','), lst) for item in sublist])
>>> [1, 2, 3, 4, 5]

How do you sum together and merge multiple numbers in a list? (Python)

So, say I have the following list and variable i:
data = [ [1, 2, 3, 1, 1], [1, 2, 3, 0, 0], [1, 2, 3, 2, 1] ]
i = 3
I would like to create a new list which will sum together and merge numbers from each sublist the ith element upwards to produce the following:
new_data = [ [1, 2, 5], [1, 2, 3], [1, 2, 6] ]
Where I have summed from each sublist the 3rd element upwards and merged the elements together. I would like to ask how, by using the standard library in Python, I can go about achieving this for an arbitrary (integer) value of i. I have the following idea in mind but I'm not sure how to put it into real Python code:
(pseudo-code)
new_data = []
for sublist in data:
new_data.append(elements before the ith element)
new_data.append(ith element onwards summed together)
You can slice your inner list by index and sum the rest with the one-liner:
>>> new_data = [row[:i-1] + [sum(row[i-1:])] for row in data]
>>> new_data
[[1, 2, 5], [1, 2, 5], [1, 2, 5]]
You can find a nice, "pythonic" one-liner in taras' answer:
new_data = [row[:i-1] + [sum(row[i-1:])] for row in data].
From pseudo-code to correct python code
I'll focus my answer on helping you transform your pseudo-code into python code.
Pseudo-code:
new_data = []
for sublist in data:
new_data.append(elements before the ith element)
new_data.append(ith element onwards summed together)
The first issue with your pseudo-code is that you are making a distinction between the list data and its sublists sublist, but you are not making a distinction between the list new_data and its sublists. Let me add a variable new_sublist in the loop:
new_data = []
for sublist in data:
new_sublist = []
new_sublist.append(elements before the ith element)
new_sublist.append(ith element onwards summed together)
new_data.append(new_sublist)
The second issue with your pseudo code: you make two calls to .append in each iteration of the loop. However, these two calls are not similar: the first call is supposed to append several elements, whereas the second call is supposed to append one element. Python makes a distinction between the two operations; if you want to add more than one element at once, use .extend instead of .append. The code becomes:
new_data = []
for sublist in data:
new_sublist = []
new_sublist.extend([elements before the ith element])
new_sublist.append(ith element onwards summed together)
new_data.append(new_sublist)
Finally we can turn your pseudo-code into proper python code, using a list slice to get the elements before the ith element, and builtin function sum along with a list slice to sum the ith element onwards:
new_data = []
for sublist in data:
new_sublist = []
new_sublist.extend(sublist[:i])
new_sublist.append(sum(sublist[i:]))
new_data.append(new_sublist)
Note that in python, looping over a list to construct a new list is such a common operation that we use the compact and elegant list comprehension syntax to do it instead of a multiline for-loop:
new_data = [sublist[:i] + [sum(sublist[i:])] for sublist in data]
Relevant documentation
list.extend and list.append;
list slices;
builtin function sum;
list comprehensions.
You can do it like so:
def merger(data, pos):
pos -= 1 # 0 based, your i above is 1 based
# collection list for result
result = []
# go over each given inner part
for inner in data:
# add it up to the correct position
result.append(inner[:pos])
# extend it by the sum of the remainder values
result[-1].append(sum(inner[pos:]))
return result
data = [ [1, 2, 3, 1, 1], [1, 2, 3, 1, 1], [1, 2, 3, 1, 1] ]
i = 3
print(merger(data,i))
Output:
[[1, 2, 5], [1, 2, 5], [1, 2, 5]]
or in short:
def merger(data, pos):
return [[inner[: pos - 1] + [sum(inner[pos - 1 :])] for inner in data]]
data = [ [1, 2, 3, 1, 1], [1, 2, 3, 1, 1], [1, 2, 3, 1, 1] ]
i = 3
new_data = [sublist[:i-1] + [sum(sublist[i-1:])] for sublist in data]
print(new_data)
>>> [[1, 2, 5], [1, 2, 5], [1, 2, 5]]

Grouping numbers in a list of floats in ascending order [duplicate]

Assume no consecutive integers are in the list.
I've tried using NumPy (np.diff) for the difference between each element, but haven't been able to use that to achieve the answer. Two examples of the input (first line) and expected output (second line) are below.
[6, 0, 4, 8, 7, 6]
[[6], [0, 4, 8], [7], [6]]
[1, 4, 1, 2, 4, 3, 5, 4, 0]
[[1, 4], [1, 2, 4], [3, 5], [4], [0]]
You could use itertools.zip_longest to enable iteration over sequential element pairs in your list along with enumerate to keep track of index values where the sequences are not increasing in order to append corresponding slices to your output list.
from itertools import zip_longest
nums = [1, 4, 1, 2, 4, 3, 5, 4, 0]
results = []
start = 0
for i, (a, b) in enumerate(zip_longest(nums, nums[1:])):
if b is None or b <= a:
results.append(nums[start:i+1])
start = i + 1
print(results)
# [[1, 4], [1, 2, 4], [3, 5], [4], [0]]
Here's a simple way to do what you're asking without any extra libraries:
result_list = []
sublist = []
previous_number = None
for current_number in inp:
if previous_number is None or current_number > previous_number:
# still ascending, add to the current sublist
sublist.append(current_number)
else:
# no longer ascending, add the current sublist
result_list.append(sublist)
# start a new sublist
sublist = [current_number]
previous_number = current_number
if sublist:
# add the last sublist, if there's anything there
result_list.append(sublist)
Just cause I feel kind, this will also work with negative numbers.
seq = [6, 0, 4, 8, 7, 6]
seq_by_incr_groups = [] # Will hold the result
incr_seq = [] # Needed to create groups of increasing values.
previous_value = 0 # Needed to assert whether or not it's an increasing value.
for curr_value in seq: # Iterate over the list
if curr_value > previous_value: # It's an increasing value and belongs to the group of increasing values.
incr_seq.append(curr_value)
else: # It was lower, lets append the previous group of increasing values to the result and reset the group so that we can create a new one.
if incr_seq: # It could be that it's empty, in the case that the first number in the input list is a negative.
seq_by_incr_groups.append(incr_seq)
incr_seq = []
incr_seq.append(curr_value)
previous_value = curr_value # Needed so that we in the next iteration can assert that the value is increasing compared to the prior one.
if incr_seq: # Check if we have to add any more increasing number groups.
seq_by_incr_groups.append(incr_seq) # Add them.
print(seq_by_incr_groups)
Below code should help you. However I would recommend that you use proper nomenclature and consider handling corner cases:
li1 = [6, 0, 4, 8, 7, 6]
li2 = [1, 4, 1, 2, 4, 3, 5, 4, 0]
def inc_seq(li1):
lix = []
li_t = []
for i in range(len(li1)):
#print (i)
if i < (len(li1) - 1) and li1[i] >= li1[i + 1]:
li_t.append(li1[i])
lix.append(li_t)
li_t = []
else:
li_t.append(li1[i])
print (lix)
inc_seq(li1)
inc_seq(li2)
You can write a simple script and you don't need numpy as far as I have understood your problem statement. Try the script below. I have tested it using Python 3.6.7 and Python 2.7.15+ on my Ubuntu machine.
def breakIntoList(inp):
if not inp:
return []
sublist = [inp[0]]
output = []
for a in inp[1:]:
if a > sublist[-1]:
sublist.append(a)
else:
output.append(sublist);
sublist = [a]
output.append(sublist)
return output
list = [1, 4, 1, 2, 4, 3, 5, 4, 0]
print(list)
print(breakIntoList(list))
Explanation:
The script first checks if input List passed to it has one or more elements.
It then initialise a sublist (variable name) to hold elements in increasing order. After that, we append input List's first element into our sublist.
We iterate through the input List beginning from it's second element (Index: 1). We keep on checking if the current element in Input List is greater than last element of sublist (by sublist[-1]). If yes, we append the current element to our sublist (at the end). If not, it means we can't hold that current element in sub-List. We append the sublist to output List and clear the sublist (for holding other increasing order sublists) and add the current element to our sublist.
At the end, we append the remaining sublist to the output List.
Here's an alternative using dict, list comprehensions, and zip:
seq = [1, 4, 1, 2, 4, 3, 5, 4, 0]
dict_seq = {i:j for i,j in enumerate(seq)}
# Get the index where numbers start to decrease
idx = [0] # Adding a zero seems counter-intuitive now; we'll see the benefit later.
for k, v in dict_seq.items():
if k>0:
if dict_seq[k]<dict_seq[k-1]:
idx.append(k)
# Using zip, slice and handling the last entry
inc_seq = [seq[i:j] for i, j in zip(idx, idx[1:])] + [seq[idx[-1:]]]
Output
print(inc_seq)
>>> [[1, 4], [1, 2, 4], [3, 5], [4], [0]]
By initiating idx = [0] and creating 2 sublists idx, idx[1:], we can zip these sublists to form [0:2], [2:5], [5:7] and [7:8] with the list comprehension.
>>> print(idx)
>>> [0, 2, 5, 7, 8]
>>> for i, j in zip(idx, idx[1:]):
print('[{}:{}]'.format(i,j))
[0:2]
[2:5]
[5:7]
[7:8] # <-- need to add the last slide [8:]

Unwanted list changing through functioncall

The general project is to re-build an enigma machine. However, the problem is this:
I have a list and I want to rearrange it in a way that the first element is appended to the same list and then the first element is deleted.
Basicly, I want this:
l = [1, 2, 3, 4]
l_new = [2, 3, 4, 1]
for this purpose I constructed the function
def switch_up(list):
list.append(list[0])
del list[0]
return list
The problem: When calling this function with a list, it does not only return the changed list, but changes the original list given as the argument.
The full code looks like this:
def switch_up(list):
list.append(list[0])
del list[0]
return list
my_list = [1, 2, 3, 4]
my_list2 = switch_up(my_list)
print(my_list)
print(my_list2)
My expected/desired output would be:
[1, 2, 3, 4]
[2, 3, 4, 1]
The output I get is:
[2, 3, 4, 1]
[2, 3, 4, 1]
You are altering the list passed into the function. That isn't a copy of the list it's the same list. You should just make a copy and return it with something like:
def switch_up(l):
# list slices will make shallow copy
return l[1:] + l[:1]
my_list = [1, 2, 3, 4]
my_list2 = switch_up(my_list)
print(my_list)
# [1, 2, 3, 4]
print(my_list2)
# [2, 3, 4, 1]
Lists are mutable in python and therefore it is assumed, that you want to do operations on the original list. If you do not want that you have to manually copy your list for example with list.copy. For more information on copy please see this stackoverflow question
All you created is a "pointer" called my_list2 to the same value as my_list if you would for example iclude my_list2[1] = 'a' the result would be:
my_list = [2, 'a', 4, 1]
my_list2 = [2, 'a', 4, 1]
And btw you should never name your variables the same as inbuilt functions, like list

Removing duplicates from a list but returning the same list

I need to remove the duplicates from a list but return the same list.
So options like:
return list(set(list))
will not work for me, as it creates a new list instead.
def remove_extras(lst):
for i in lst:
if lst.count(i)>1:
lst.remove(i)
return lst
Here is my code, it works for some cases, but I dont get why it does not work for remove_extras([1,1,1,1]), as it returns [1,1] when the count for 1 should be >1.
You can use slice assignment to replace the contents of the list after you have created a new list. In case order of the result doesn't matter you can use set:
def remove_duplicates(l):
l[:] = set(l)
l = [1, 2, 1, 3, 2, 1]
remove_duplicates(l)
print(l)
Output:
[1, 2, 3]
You can achieve this using OrderedDict which removes the duplicates while maintaining order of the list.
>>> from collections import OrderedDict
>>> itemList = [1, 2, 0, 1, 3, 2]
>>> itemList[:]=OrderedDict.fromkeys(itemList)
>>> itemList
[1, 2, 0, 3]
This has a Runtime : O(N)

Categories