increment of list elements in a certain pattern - python

I have a list for example:
[1,2,3,4]
I want to have ten repeats of the list, and every element increase by 1 than the previous element like:
[1,2,3,4,2,3,4,5,3,4,5,6................40 elements]

Thanks for the previous answers!
The closest answer I got so far:
list = [1,2,3,4]
n = 4 #number of elements in the list
newList = [ ]
for i in range(10):
for element in list:
newList.append(element + i*n)
print(newList)
print(len(newList))
The output:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40]
40

temp = [1, 2, 3, 4]
lst = [i + j for i in range(9) for j in temp]
print(lst)
# which equals to this:
temp = [1, 2, 3, 4]
lst2 = []
for i in range(9):
for j in temp:
lst2.append(i + j)
print(lst2)

plz have a look. I don't think it goes upto [1,2,..40] , only goes upto[1,2,.. 14].
At each iteration you are increasing the value by 1 so, after 10 times repeating every no in the array will be increased by 10. So 4 will be 14 which will be the last element not 40.
Here's my code according to your requirement,
arr = [1,2,3,4]
answer = [ ]
for i in range(11):
for element in arr:
answer.append(element + i)
print(answer)

Related

How to find the index of the last odd number in a list, without reversing the list?

Have this so far, and essentially want to get there is something wrong with the position of last_odd as the compiler says the pop index is out of range?
def remove_last_odd(numbers):
has_odd = False
last_odd = 0
for num in range(len(numbers)):
if numbers[num] % 2 == 1:
has_odd = True
last_odd = numbers[num]
if has_odd:
numbers.pop(last_odd)
numbers = [1, 7, 2, 34, 8, 7, 2, 5, 14, 22, 93, 48, 76, 15, 6]
Remove the item at the given position in the list, and return it. If no index is specified, a.pop() removes and returns the last item in the list.
So basically, the solution to your problem would be to replace last_odd = numbers[num] with last_odd = num.
As #DeepSpace said, list.pop will
Remove the item at the given position in the list, and return it. If no index is specified, a.pop() removes and returns the last item in the list.
So basically, the solution to your problem would be to replace last_odd = numbers[num] with last_odd = num.
list.pop() receive index as argument and remove the value. So, last_odd should be assigned to num instead of numbers[num]
Your function doesn't have return value yet. It should return numbers list.
def remove_last_odd(numbers):
for num in range(len(numbers)):
if numbers[num] % 2 == 1:
last_odd = num
numbers.pop(last_odd)
return numbers
numbers = [1, 7, 2, 34, 8, 7, 2, 5, 14, 22, 93, 48, 76, 15, 6]
print(remove_last_odd(numbers))
# [1, 7, 2, 34, 8, 7, 2, 5, 14, 22, 93, 48, 76, 6]
Or iterating numbers value and using remove() method instead of pop():
def remove_last_odd(numbers):
for num in numbers:
if num % 2: last_odd = num
numbers.remove(last_odd)
return numbers
numbers = [1, 7, 2, 34, 8, 7, 2, 5, 14, 22, 93, 48, 76, 15, 6]
print(remove_last_odd(numbers))
# [1, 7, 2, 34, 8, 7, 2, 5, 14, 22, 93, 48, 76, 6]
No need to reverse the list but you can search it in reverse.
def remove_last_odd(numbers):
for i in range(len(numbers)-1, -1, -1):
if numbers[i] & 1:
numbers.pop(i)
break
numbers = [1, 7, 2, 34, 8, 7, 2, 5, 14, 22, 93, 48, 76, 15, 6]
remove_last_odd(numbers)
print(numbers)
Output:
[1, 7, 2, 34, 8, 7, 2, 5, 14, 22, 93, 48, 76, 6]
Option:
If you insist on a 'forward' search then:
def remove_last_odd(numbers):
ri = -1
for i, v in enumerate(numbers):
if v & 1:
ri = i
if ri >= 0:
numbers.pop(ri)
To get the index of the last odd element you can use the reversed() iterator which will not reverse the original list object.
A quick way to get the index is:
>>> numbers = [1, 7, 2, 34, 8, 7, 2, 5, 14, 22, 93, 48, 76, 15, 6]
>>> -next(filter(lambda v: v[1]%2==1, enumerate(reversed(numbers))))[0]
-1
Even for very large lists with a lot of even numbers at the end the result will be delivered quite quick (compared with the proposed code):
>>> from timeit import timeit
>>> def find_last_odd(numbers):
for num in range(len(numbers)):
if numbers[num] % 2 == 1:
last_odd = num
return last_odd
>>> numbers2=numbers+([2]*10000) # create a list with 10000 even numbers at the end!
>>> timeit(lambda: find_last_odd(numbers2),number=100)
0.5675344999999936
>>> timeit.timeit(lambda: -next(filter(lambda v: v[1]%2==1, enumerate(reversed(numbers2)))).__getitem__(0),number=100)
0.10892959999998197

Python: Difference between two positions in one list depending on rule set for another list

Consider two lists of identical length:
t is a list of irregular-intervals of times in seconds, arranged chronologically
pt is a list of sequences of numbers 1,2,3 wsuch that a 1 is followed by a consecutive string of 2's, then followed by a 3.
1 = start of event, 2 = continuation of event, 3 = end of event
This means that for a single event, the sequence begins with a single 1, is followed by a consecutive string of 2s (how many times it repeats will vary), and finally ends in a single 3.
There is more than 1 event contained in this vector
For example, the input could look like:
# |--Event #1-| |---Event #2----| |Event #3 |
pt = [1, 2, 2, 3, 1, 2, 2, 2, 3, 1, 2, 3 ]
t = [1, 10, 13, 14, 17, 20, 21, 25, 37, 32, 33, 38]
Is there a 1-liner that doesn't involve multiple nested loops that we could use that would calculate the difference in time values in t for each event sequence in pt?
For example, the desired output for the above inputs would be a list of length 3 (because there are 3 events) where the output is
Output: [13, 20, 6]
### Explanation:
# 13 = 14-1 = t[position where pt shows first 3] - t[position where pt shows first 1]
# 20 = 37-17 = t[position where pt shows second 3] - t[position where pt shows second 1]
# 6 = 38-32 = t[position where pt shows third 3] - t[position where pt shows third 1]
using pure python:
pt = [1, 2, 2, 3, 1, 2, 2, 2, 3, 1, 2, 3 ]
t = [1, 10, 13, 14, 17, 20, 21, 25, 37, 32, 33, 38]
l = [y for x, y in zip(pt,t) if x in [1,3]]
print([l[i:i+2][1] - l[i:i+2][0] for i in range(0, len(l), 2)])
[13, 20, 6]
using more_itertools.chunked():
from more_itertools import chunked
print([y-x for x,y in chunked([y for x, y in zip(pt,t) if x in [1,3]], 2)])
[13, 20, 6]
explanation
If you look close, we see this list comprehension occurring multiple times. This is the center of the solution!
[y for x, y in zip(pt,t) if x in [1,3]]
So, what's going on?
Using the zip function, we make a list of the paired elements, and if the x element (1st list element pair) is either 1 or 3 we add it to the list.
This gives us a list of the differences we need to find.
#|---| |----| |----|
[1, 14, 17, 37, 32, 38]
Now comes the second part, getting the differences from these. We essentially need to make pairs from this, the method I'm going to use here is chunking. The pure python way to partition a list into chunks is as follows:
#given a list l
chunklen = 2
[l[i:i+chunklen] for i in range(0, len(l), chunklen)]
using this we could partition the [1, 14, 17, 37, 32, 38] list to:
[[1, 14], [17, 37], [32, 38]]
but it's far simpler to just get the differences immediately!
l[i:i+chunklen][1]-l[i:i+chunklen][0]
#given l[i:i+chunklen] as [1, 14] this would return 14-1 i.e. 13
This seems to work
pt = [1, 2, 2, 3, 1, 2, 2, 2, 3, 1, 2, 3 ]
t = [1, 10, 13, 14, 17, 20, 21, 25, 37, 32, 33, 38]
st = 0
lst = []
for x in zip(pt,t):
if x[0] == 1: st = x[1]
if x[0] == 3:
d = x[1] - st
lst.append(d)
print(lst)
Output
[13, 20, 6]
Code:
pt = [1, 2, 2, 3, 1, 2, 2, 2, 3, 1, 2, 3 ]
t = [1, 10, 13, 14, 17, 20, 21, 25, 37, 32, 33, 38]
events_t =[]
arr = []
for pt_ele, t_ele in zip(pt, t):
arr.append(t_ele)
if pt_ele == 3:
events_t.append(arr)
arr = []
print(events_t)
res = [i[-1] - i[0] for i in events_t]
print(res)
Output:
[[1, 10, 13, 14], [17, 20, 21, 25, 37], [32, 33, 38]]
[13, 20, 6]

How to split a sorted list into sub lists when two neighboring value difference is larger than a threshold

input:
a sorted list, like this:[1,2,3,8,10,15,16,17,18,22,23,27,30,31]
a threshold, like this: max_diff = 2
expected output:
a list of sub lists; each sub list contains the values that the neighboring difference is smaller than max_diff, like this: [[1, 2, 3], [8, 10], [15, 16, 17, 18], [22, 23], [27], [30, 31]]
Here's how I did this, I am wondering if there is a better way to do this.
test_list = [1,2,3,8,10,15,16,17,18,22,23,27,30,31]
max_diff = 2
splited_list = []
temp_list = [test_list[0]]
for i in xrange(1,len(test_list)):
if test_list[i] - temp_list[-1] > max_diff:
splited_list.append(temp_list)
temp_list = [test_list[i]]
else:
temp_list.append(test_list[i])
if i == len(test_list) -1:
splited_list.append(temp_list)
print splited_list
You can use enumerate and zip function within a list comprehension to find the indices of the elements that value difference is larger than 2, then split your list based on index list :
>>> li =[1, 2, 3, 8, 10, 15, 16, 17, 18, 22, 23, 27, 30, 31]
>>> inds=[0]+[ind for ind,(i,j) in enumerate(zip(li,li[1:]),1) if j-i>2]+[len(li)+1]
>>> [li[i:j] for i,j in zip(inds,inds[1:])]
[[1, 2, 3], [8, 10], [15, 16, 17, 18], [22, 23], [27], [30, 31]]
>>> a = [1,2,3,8,10,15,16,17,18,22,23,27,30,31]
>>> b = a[1:] #offset by 1 position
>>> b
[2, 3, 8, 10, 15, 16, 17, 18, 22, 23, 27, 30, 31]
>>> c = [(i[1] - i[0]) for i in zip(a[:-1], b)]
>>> c #position diff
[1, 1, 5, 2, 5, 1, 1, 1, 4, 1, 4, 3, 1]
>>> d = [i[0] for i in enumerate(c) if i[1] > 2]
>>> d #split position
[2, 4, 8, 10, 11]
>>> e = [-1]+d+[len(a)]
>>> e #add start end to split position
[-1, 2, 4, 8, 10, 11, 14]
>>> [a[l[0]+1: l[1]+1] for l in zip(e, e[1:])]
[[1, 2, 3], [8, 10], [15, 16, 17, 18], [22, 23], [27], [30, 31]]
#split result
Rearranging your lines leads to a more compact form:
test_list = [1,2,3,8,10,15,16,17,18,22,23,27,30,31]
max_diff = 2
splited_list = []
prev_element = float('-inf')
for element in test_list:
if element - prev_element > max_diff:
splited_list.append([])
splited_list[-1].append(element)
prev_element = element
print splited_list
Works on all iterables
def split_by_threshold(seq, max_diff=2):
it = iter(seq)
last = next(it)
part = [last]
for curr in it:
if curr - last > max_diff:
yield part
part = []
part.append(curr)
last = curr
yield part
l = [1,2,3,8,10,15,16,17,18,22,23,27,30,31]
print(list(split_by_threshold(l)))

Python - Function that sums list's with error

def somalist (lista):
listasoma = [0,0,0,0,0,0,0,0,0,0,0]
for i in lista:
for g in i:
if i.index(g) != 0 and i.index(g) != 1 and i.index(g) != 2 and i.index(g) != 3:
listasoma[i.index(g)] += g
else:
listasoma[i.index(g)] = g
print(listasoma)
return(listasoma)
x = [[1,2,3,4,5,6,7,8,9,10,11],[1,2,3,4,5,6,7,8,9,10,11],[1,2,3,4,5,6,7,8,9,10,11]]
print(somalist(x))
is that the function, it works doing the sum of each sublist but it preserves the the index [0], [1], [2] and [3] and sum the anothers. In this example I will use the list x, in this list the function works correctly. The exit of the program is:
[1, 2, 3, 4, 32, 18, 21, 24, 27, 30, 22]
is what I've said it preserves the members [0],[1],[2],[3] and sum the other indices of each sublist.
But when we use some number more than once, it fails.
using:X = [[1,2,3,4,5,6,7,8,9,10,11],[1,2,3,4,**6**,6,7,8,9,10,11],[1,2,3,4,5,6,7,8,9,10,11]]
the 6 (index 4) in second sublist was writen twice (the another at the index 5 at the same sublist)
the exit was :[1, 2, 3, 4, **22**, 12, 21, 24, 27, 30, 33]
It's wrong!
The correct exit should be: [ 1, 2, 3, 4, 16, 18, 21, 24, 27, 30, 33]
Can someone tell me where my code is wrong?
I would recommend ditching the index() approach entirely.
def somalist (lista):
return lista[0][:4] + [sum(item) for item in list(zip(*lista))[4:]]
This works on lists with repeated elements.
v
>>> x = [[1,2,3,4,5,6,7,8,9,10,11],[1,2,3,4,5,6,7,8,9,10,11],[1,2,3,4,5,6,7,8,9,10,11]]
>>> X = [[1,2,3,4,5,6,7,8,9,10,11],[1,2,3,4,6,6,7,8,9,10,11],[1,2,3,4,5,6,7,8,9,10,11]]
>>> print(somalist(x))
[1, 2, 3, 4, 15, 18, 21, 24, 27, 30, 33]
>>> print(somalist(X))
[1, 2, 3, 4, 16, 18, 21, 24, 27, 30, 33]
^^

Create a list with six sublists of random numbers

I'm totally new with Python; however, I would like to make a list of 6 sub-lists, each of which contains 4 random values between 0 and 30.
The answer should print like this:
lst[0] = [1,4,4,5]
lst[1] = [23,14,5,8]
...
lst[5] = [8,9,18,27]
Here is the simple one-liner that'll get it done:
from random import randint
rand_list = [[randint(0, 30) for i in range(4)] for n in range(6)]
>>>rand_list
[[28, 17, 5, 9],
[27, 29, 3, 8],
[18, 13, 4, 11],
[15, 12, 11, 19],
[17, 8, 22, 30],
[24, 6, 9, 1]]
If you want to get fancy, you can easily expand it into a function that will allow you to specify the list-sizes as inputs to the function:
def rand_lists(num_lists, num_vals):
return [[randint(0, 30) for i in range(num_vals)] for n in range(num_lists)]
>>> rand_lists(2, 7)
[[17, 8, 29, 2, 9, 26, 16],
[24, 22, 5, 10, 11, 0, 10]]
For a one-liner:
from random import randint
lst = [[randint(0, 30) for col in range(4)] for row in range(6)]
Which is equivalent to(in pure python):
lst = []
for row in range(6):
r = []
lst.append(r)
for col in range(4):
r.append(randint(0, 30))

Categories

Resources