Related
I have 2 lists, for example:
list1 = [1, 2, 2, 3, 3, 4]
list2 = [1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5]
I want to get a list 3 which will include all numbers from list2 matching the numbers from list1:
list3 = [1, 1, 2, 2, 3, 3, 4, 4, 4]
I was trying to use 2 while loops to go through list1 and list2 and match numbers, but it gives me wrong number of values:
listO = [1, 2, 2, 3, 3, 4]
listX = [1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5]
x_temp = []
a = 0
b = 0
while a < len(listO):
while b < len(listX):
if listO[a] == listX[b]:
x_temp.append(listX[b])
print("Outlier a:" , listO[a] )
listX.remove(listX[b])
b+=1
b=0
a+=1
list3 = [1, 2, 2, 3, 3, 4, 4]
Is there any way to do it using loops?
Please do NOT provide solution using set() it doesn`t work for my lists!
With a for loop:
listO = [1, 2, 2, 3, 3, 4]
listX = [1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5]
x_temp = []
for x in listX:
if x in listO:
x_temp.append(x)
# [1, 1, 2, 2, 3, 3, 4, 4, 4]
You can use a list comprehension for this.
list1 = [1, 2, 2, 3, 3, 4]
list2 = [1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5]
list3 = [i for i in list2 if i in list1]
# [1, 1, 2, 2, 3, 3, 4, 4, 4]
Say I have a list as follows:
list_sequences = [1, 2, 3, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3, 2, 3, 2, 3, 1]
I want to create another list with the count of the occurrences, but the occurrence of 2 and 3 is reset after an occurrence of 1.
Something like:
occurrence_list = [1, 1, 1, 2, 2, 2, 1, 1, 3, 1, 1, 2, 2, 3, 3, 4, 4, 4]
is there a simple pythonic way to do so?
You can use a defaultdict to keep account of what is going on:
from collections import defaultdict
list_sequences = [1, 2, 3, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3, 2, 3, 2, 3, 1]
def make_occurrence(seq):
counter = defaultdict(int)
occurrence = []
for item in seq:
count = counter[item] + 1
if item == 1:
counter.clear()
counter[item] = count
occurrence.append(count)
return occurrence
print(make_occurrence(list_sequences))
Output as requested
I am breaking my head around this small issue which I am sure can (and should) be solved recursively.
# split list in sublists based on length of first element.
list = [3, 1, 2, 3, 4, 1, 2, 3, 4]
#* #*
# *number of elements of the sublist
It is better shown than explained, the above should result to:
[[1, 2, 3], [1, 2, 3, 4]]
The lists I am processing always respect this logic, the first element is always the length of the following n elements.
EDIT:
Based on some of the suggestions, I simply added a yield to get it done lazily.
def split(ls):
"""
func that given a list extracts sub lists with the length indicated by the first element
[2, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4] => [[1, 2], [1, 2, 3], [1, 2, 3, 4]]
"""
res = []
while ls:
dim = ls[0]
yield ls[1:dim + 1]
ls = ls[dim + 1:]
return res
>>> list(split([2, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4]))
[[1, 2], [1, 2, 3], [1, 2, 3, 4]]
Simple slicing will do:
>>> a = [3, 1, 2, 3, 4, 1, 2, 3, 4]
>>> c = []
>>> while len(a) :
... b = a[0]
... c.append( a[1:b+1] )
... a = a[b+1:]
...
>>> c
[[1, 2, 3], [1, 2, 3, 4]]
Here is a way to achieve what you want:
numbers = [3, 1, 2, 3, 4, 1, 2, 3, 4]
result = []
def split_list(list_):
first = list_.pop(0)
result.append(list_[:first])
if len(list_[first:]) > 0:
split_list(list_[first:])
split_list(numbers)
print(result)
You can use itertools.islice here.
>>> from itertools import islice
>>> lst = [3, 1, 2, 3, 4, 1, 2, 3, 4]
>>> def chunks(lst):
... t=iter(lst)
... c=next(t,None)
... while c:
... yield list(islice(t,None,c))
... c=next(t,None)
...
>>> list(chunks(lst))
[[1, 2, 3], [1, 2, 3, 4]]
I've edited my answer as inspired by someone else's in this thread. This doesn't consume the original array and uses recursion instead of looping.
numbers = [3, 1, 2, 3, 4, 1, 2, 3, 4, 3,1,1,1,1]
def do_take(numbers: []):
result = []
to_take = numbers[0]
result.append(numbers[1:to_take + 1])
if len(numbers) > to_take:
result.append(do_take(numbers[to_take + 1:]))
return result
print(do_take(numbers))
print(numbers)
Results in the following output:
# python /tmp/breakup.py
[[1, 2, 3], [[1, 2, 3, 4], [[1, 1, 1], [[]]]]]
[3, 1, 2, 3, 4, 1, 2, 3, 4, 3, 1, 1, 1, 1]
I know how to get ALL combinations of a list in Python with itertools, but what if I want to limit the amount of repeats?
So, if I have [1, 2, 3, 4, 5]
But I want to limit combinations to only 3 repeats of each item (with a fixed length of the final list, say 10):
[1, 1, 1, 2, 3, 3, 5, 5, 5, 4]
[1, 2, 3, 3, 3, 4, 5, 5, 4, 4]
[4, 4, 1, 1, 1, 5, 2, 2, 2, 3]
and so on. How do I do this?
This would work:
import random
L = [1, 2, 3, 4, 5]
L3 = L * 3
random.shuffle(L3)
L3[:10]
I don't know if there is a more elegant way but that seems to work:
from itertools import combinations_with_replacement
a = [1, 2, 3, 4, 5] # can contain letters as well
all_combinations = combinations_with_replacement(a, 10)
filtered_results = []
for current in all_combinations:
throw_away = False
for item in current:
if current.count(item) > 3:
throw_away = True
break
if not throw_away:
filtered_results.append( current )
for j in filtered_results:
print(j)
You could do it the following way: Use [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5] and use itertools.combination(the list from above, 10). That would mean that each element occurs at most three times in a resulting list.
Example with smaller list:
Edited to ensure every combination occurs exactly once, the combinations occur in random order and, finally, every combination has a random order.
Also incorporated the idea of Mike Müller to just multiply the list by 3.
import itertools
import random
combinations = set()
for c in itertools.combinations(sorted([1, 2, 3] * 3), 5):
combinations.add(c)
shuffledCombinations = list(combinations)
random.shuffle(shuffledCombinations)
for combination in shuffledCombinations:
copiedCombination = list(combination)
random.shuffle(copiedCombination)
print copiedCombination
which will give:
[2, 1, 3, 2, 2]
[2, 2, 1, 1, 2]
[3, 3, 3, 1, 2]
[2, 2, 3, 2, 3]
[1, 2, 3, 1, 2]
[1, 1, 1, 2, 3]
[2, 1, 1, 1, 2]
[3, 3, 1, 1, 1]
[1, 3, 3, 3, 1]
[3, 2, 3, 2, 3]
[3, 2, 1, 2, 3]
[1, 1, 2, 3, 3]
I have a problem where I want to have a nested for loop concatenate a string. For some reason I'm not getting the correct output. Can someone give me some advice? This should be simple.
newRow = []
matrix = []
for i in range(0,3):
for j in range(0,5):
newRow.append(j)
matrix.append(newRow)
print matrix
python test.py
[[0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4],
[0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4],
[0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4]]
I want it to print...
[[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4]]
You keep adding to the same newRow. If you want to get a clean row, you need to create an empty one on each iteration:
matrix = [] newRow = [] <- the same array
for i in range(0,3): matrix = []
newRow = [] <- a new array for i in range(0,3):
for j in range(0,5): instead of for j in range(0,5):
newRow.append(j) newRow.append(j)
matrix.append(newRow) matrix.append(newRow)
There are, of course, more pythonic ways of achieving this, but I'm trying to point out what the problem with the code is.
You can make this if you want nested loop:
matrix = [ [ i for i in range(5)] for j in range(3)]
print matrix
[[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]
matrix = []
for i in range(0,3):
matrix.append(list(range(0, 5)))
or even:
matrix = [list(range(0, 5)) for i in range(0, 3)]
You are close, its just a matter of properly scoping:
matrix = []
for i in range(0,3):
newRow = []
for j in range(0,5):
newRow.append(j)
matrix.append(newRow)
print matrix
Whatever you do,
DON'T DO THIS
DON'T DO THIS
DON'T DO THIS:
>>> x = [range(0,5)]*3
>>> x
[[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]
>>> x[0][0] = 'LOL'
>>> x
[['LOL', 1, 2, 3, 4], ['LOL', 1, 2, 3, 4], ['LOL', 1, 2, 3, 4]]
use a list comprehension.