Looking for a pythonic way to repeat sequences of fixed length while incrementing the sequence digits until max length is reached.
As of now, the code uses while loop and four variables one being the list itself to complete the logic as below,
l = []
i, repeat, max_len = 0, 3, 20
while True:
if len(l) + repeat <= max_len:
l.extend([i] * repeat)
else:
repeat = max_len - len(l)
l.extend([i] * repeat)
break
i += 1
The above code produces
l = [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6]
Thus, repeating a fixed length sequence of 3 units until the maximum length of 20 is reached (omit any last digits of sequence outside max_len permitted)
Is there a pythonic way of doing the same?
How about this one:
[int(i/repeat) for i in range(max_len)]
Well this will make exactly your list using list comprehension.
l = [i//(repeat) for i in range(max_len)]
# [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6]
But I think there is a bug in the original function because there should be three 5s at the end.
l = [i//(repeat) for i in range(max_len//repeat * repeat)]
# [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5]
With list comprehensions
>>> i, repeat, max_len = 0, 3, 20
>>> q = max_len//repeat
>>> [x for x in range(i, i+q) for y in range(repeat)]+[i+q for y in range(max_len%repeat)]
[0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6]
With a different starting value:
>>> i = 5
>>> [x for x in range(i, i+q) for y in range(repeat)]+[i+q for y in range(max_len%repeat)]
[5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11]
Related
So I am working on a script for numerical one time pads
but the issue is that I would like the result of the sums to stay within a specific range
of 0 to 10 so that
2-4=9 [9, 10, 0, 1, 2]
4-9=6 [6, 7, 8, 9, 10, 0, 1, 2, 3, 4]
7+8=4 [7, 8, 9, 10, 0, 1, 2, 3, 4]
Here is my script
#list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
#sum = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0] 1 = addition, 0 = subtraction
#of = [2, 4, 3, 9, 5, 6, 8, 7, 0, 1,]
length = len(list)
i = 0
while i < length:
x = list[i]
s = sum[i]
y = of[i]
if s == 1:
z = x + y
else:
z = x - y
print(z)
i += 1
You need to use modular arithmetic
>>> (2-9)%11
4
>>> (4-9)%11
6
>>> (7+8)%11
4
In a list of integer values
a = [4, 8, 2, 3, 8, 5, 8, 8, 1, 4, 8, 2, 1, 3]
I have to find the index of the last item with value 8. Is there more elegant way to do that rather than mine:
a = [4, 8, 2, 3, 8, 5, 8, 8, 1, 4, 8, 2, 1, 3]
for i in range(len(a)-1, -1, -1):
if a[i] == 8:
print(i)
break
Try This:
a = [4, 8, 2, 3, 8, 5, 8, 8, 1, 4, 8, 2, 1, 3]
index = len(a) - 1 - a[::-1].index(8)
Just reverse the array and find first index of element and then subtract it from length of array.
>>> lst = [4, 8, 2, 3, 8, 5, 8, 8, 1, 4, 8, 2, 1, 3]
>>> next(i for i in range(len(lst)-1, -1, -1) if lst[i] == 8)
10
This throws StopIteration if the list doesn't contain the search value.
Use sorted on all indexes of items with a value of 8 and take the last value, or using reverse = True take the first value
x = sorted(i for i, v in enumerate(a) if v == 8)[-1]
print(x) # => 10
Given an iterator i, I want an iterator that yields each element n times, i.e., the equivalent of this function
def duplicate(i, n):
for x in i:
for k in range(n):
yield x
Is there an one-liner for this?
Related question: duplicate each member in a list - python, but the zip solution doesn't work here.
This is my simple solution, if you want to duplicate each element same times. It returns a generator expression, which should be memory efficient.
def duplicate(i, n):
return (k for k in i for j in range(n))
An example usage could be,
print (list(duplicate(range(1, 10), 3)))
Which prints,
[1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8,
8, 9, 9, 9]
itertools.chain.from_iterable(itertools.izip(*itertools.tee(source, n)))
Example:
>>> x = (a**2 for a in xrange(5))
>>> list(itertools.chain.from_iterable(itertools.izip(*itertools.tee(x, 3))))
[0, 0, 0, 1, 1, 1, 4, 4, 4, 9, 9, 9, 16, 16, 16]
Another way:
itertools.chain.from_iterable(itertools.repeat(item, n) for item in source)
>>> x = (a**2 for a in xrange(5))
>>> list(itertools.chain.from_iterable(itertools.repeat(item, 3) for item in x))
[0, 0, 0, 1, 1, 1, 4, 4, 4, 9, 9, 9, 16, 16, 16]
Use a generator expression:
>>> x = (n for n in range(4))
>>> i = (v for v in x for _ in range(3))
>>> list(i)
[0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3]
How do you extract a value out of n of a list in python ?
For example :
n = 3
l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
And I would like to get
[0, 3, 6, 9]
I know I can do this with a for, but is there any more pythonic and short way ?
You can do a simple list comprehension
>>> n = 3
>>> l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [i for i in l if i%n==0]
[0, 3, 6, 9]
If your list is always like that, then you can use strides
>>> l[::3]
[0, 3, 6, 9]
Tip
Use range to generate lists like that
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Using slicing would be the most pythonic way:
In [1]: n = 3
In [2]: l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [3]: l[::n]
Out[3]: [0, 3, 6, 9]
Use a slice with stride:
l[::n]
Demo:
>>> n = 3
>>> l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> l[::n]
[0, 3, 6, 9]
print l[::3] # slice with step n = 3
All,
I want define an int(987654321) <=> [9, 8, 7, 6, 5, 4, 3, 2, 1] convertor, if the length of int number < 9, for example 10 the list will be [0,0,0,0,0,0,0,1,0]
, and if the length > 9, for example 9987654321 , the list will be [9, 9, 8, 7, 6, 5, 4, 3, 2, 1]
>>> i
987654321
>>> l
[9, 8, 7, 6, 5, 4, 3, 2, 1]
>>> z = [0]*(len(unit) - len(str(l)))
>>> z.extend(l)
>>> l = z
>>> unit
[100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1]
>>> sum([x*y for x,y in zip(l, unit)])
987654321
>>> int("".join([str(x) for x in l]))
987654321
>>> l1 = [int(x) for x in str(i)]
>>> z = [0]*(len(unit) - len(str(l1)))
>>> z.extend(l1)
>>> l1 = z
>>> l1
[9, 8, 7, 6, 5, 4, 3, 2, 1]
>>> a = [i//x for x in unit]
>>> b = [a[x] - a[x-1]*10 for x in range(9)]
>>> if len(b) = len(a): b[0] = a[0] # fix the a[-1] issue
>>> b
[9, 8, 7, 6, 5, 4, 3, 2, 1]
I tested above solutions but found those may not faster/simple enough than I want and may have a length related bug inside, anyone may share me a better solution for this kinds convertion?
Thanks!
Maybe I am missing something, but shouldn't this be enough (without value checking)?
def int_to_list(i):
return [int(x) for x in str(i).zfill(9)]
def list_to_int(l):
return int("".join(str(x) for x in l))
Reference: str.zfill
And what about :
def int_to_list(num)
return list ("%010d" % num)
def convert(number):
stringified_number = '%s' % number
if len(stringified_number) < 9:
stringified_number = stringified_number.zfill(9)
return [int(c) for c in stringified_number]
>>> convert(10)
[0, 0, 0, 0, 0, 0, 0, 1, 0]
>>> convert(987654321)
[9, 8, 7, 6, 5, 4, 3, 2, 1]
To place an integer of any length into a list in sequence by integer digit -
a = 123456789123456789123456789123456789123456789123456789
j = len('{}'.format(a))
b = [0 for i in range(j)]
c = 0
while j > 0:
b [c] = a % 10**j // 10**(j-1)
j = j-1
c = c + 1
print(b)
output -
[1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9]
you can put the condition on j for the alternate assignment to b.