Extracting ordered sub sequence from list - python

I am trying to extract ORDERED sequence. For example,
a = [2, 3, 1, 4, 6, 8, 5, 9]
b = [3, 8, 9, 4, 10, 11, 5]
c = [3,4,5]
c must hold values common to a and b where [3,4,5] appear in an order, [8,9] must not appear because it comes between [3,4] in a and between [4,5] in b
Another example as follows:
a = [2, 3, 1, 4, 6, 8, 9, 10]
b = [2, 8, 3, 9, 10, 11]
c = [2,3,9,10]
I tried the following code:
a = [2, 3, 1, 4, 6, 8, 5, 9]
b = [3, 8, 9, 4, 10, 11, 5]
for i in a:
for j in b:
if i==j:
print i
break
I get the WRONG results as follows:
3
4
8
5
9
How do I avoid getting such an output? Also is there a pythonic way to this?

Use a tempval and store the context. This can be done using the enumerate builtin function. Now using slices you will get the output as expected.
a = [2, 3, 1, 4, 6, 8, 5, 9]
b = [3, 8, 9, 4, 10, 11, 5]
tempval = 0
for i in a:
for ind,j in enumerate(b[tempval:]):
if i==j:
print i
tempval = ind
Output is
3
4
5

#Ekoji, To get the list in order, you can try the below code. Sort the elements in the list a, So you get them in order.
a = [2, 3, 1, 4, 6, 8, 5, 9]
b = [3, 8, 9, 4, 10, 11, 5]
a.sort()
# use your logic
for i in a:
for j in b:
if i == j:
print ("i is : %s j is :%s" % (i , j))
if len(c) > 1:
print c
print ("validation : %s :%s" %( c[-1] , i-1))
if c[-1:] == [i-1]:
print "continue"
c.append(i)
else:
print "do Nothing"
else:
c.append(i)
print c
Output :
[3, 4]
validation : 4 :4
continue
[3, 4, 5]
validation : 5 :7
do Nothing
[3, 4, 5]
validation : 5 :8
do Nothing
[3, 4, 5]

Related

Creating a list of N numbers from existing list each repeated K times

I believe this is an easy problem to solve. I have searched and found a few similar answers but not an efficient way to exactly what I want to achieve.
Assuming the following list:
x = [6, 7, 8]
I want to create a new list by repeating each number k times. Assuming k=3, the result should be:
xr = [6, 6, 6, 7, 7, 7, 8, 8, 8]
I was able to accomplish this using nest loops, which I believe is very inefficient:
xr = []
for num in x: # for each number in the list
for t in range(3): # repeat 3 times
xx2.append(num)
I also tried:
[list(itertools.repeat(x[i], 3)) for i in range(len(x))]
but I get:
[[6, 6, 6], [7, 7, 7], [8, 8, 8]]
Is there a more efficient direct method to accomplish this?
You can use list comprehension:
x = [6, 7, 8]
k = 3
out = [v for v in x for _ in range(k)]
print(out)
Prints:
[6, 6, 6, 7, 7, 7, 8, 8, 8]
def repeat_k(l,k):
lo = []
for x in l:
for i in range(k):
lo.append(x)
return lo
print (repeat_k([1,2,3],5))
Output:
[1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3]
With list comprehension:
def repeat_k(l,k):
return [ x for x in l for i in range(k) ]
print (repeat_k([1,2,3],5))
Output:
[1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3]
Another possibility:
>>> x = [6, 7, 8]
>>> k = 3
>>> l = []
>>> for item in x:
... l += k * [item]
...
>>> l
[6, 6, 6, 7, 7, 7, 8, 8, 8]
You can create a convenient function:
def repeat(it, n):
for elem in it: yield from [elem] * n
Use it like:
>>> list(repeat(x, n=3))
[6, 6, 6, 7, 7, 7, 8, 8, 8]
Thanks, everyone for the answers.
It seems there is an easier and more direct way to solve this using Numpy.
np.repeat(x, 3).tolist()
prints exactly what I needed:
[6, 6, 6, 7, 7, 7, 8, 8, 8]
import itertools
x=[4,5,6]
k=3
res = list(itertools.chain.from_iterable(itertools.repeat(i, K) for i in test_list))
print (res)
It can also be solved using python inbuilt functions of itertools library. The repeat function does the task of repetition and grouping into a list is done by the from_iterable function.

Finding the missing number in python

I am a beginner in programming. I saw the challenge about missing numbers on Geeks for Geeks. The solutions offered are quite complex for me. I wonder if my solution is correct because it seems too easy. Thanks!
A = [1, 2, 3, 4, 5, 7]
def missing():
for i in range (len(A)):
if A[i+1] != A[i] + 1:
return A[i] + 1
missing()
This is your example but with list comprehension. This will allow you to return a list of all the missing numbers. Keep in mind your sollution only works for gaps == 1.
A = [1, 3, 4, 5, 7]
def missing(A):
x = [A[i] + 1 for i in range (len(A)-1) if A[i+1] != A[i] + 1]
return x
print(missing(A))
output
[2, 6]
I would say that your code is quite unstable, but it may work.
I would say this is working better
A = [1, 2, 3, 4, 5, 7]
def missing():
for i in range(len(A)):
result = 0
if A[i+1] != A[i] + 1:
result A[i] + 1
return result
missing()
But also what if 1 is the missing number?
This code below allows 1 to be the missing number
A = [1, 2, 3, 4, 5, 7]
def missing():
if A[0] != 1:
result = 1
return result
for i in range(len(A)):
result = 0
if A[i+1] != A[i] + 1:
result A[i] + 1
return result
missing()
You can just check that each number in the range of numbers from the first element in the list to the last element in the list exists in the list.
for Loop:
>>> def missing_num(numlist):
numlist.sort()
missing = []
for i in range(numlist[0], numlist[-1]+1):
if i not in numlist:
missing.append(i)
return missing
>>> missing_num([1, 2, 3, 4, 5, 7])
[6]
List Comprehension:
>>> def missing_num(numlist):
numlist.sort()
nums = list(range(numlist[0], numlist[-1]+1))
return [i for i in nums if i not in numlist]
>>> missing_num([1, 2, 3, 4, 5, 7])
[6]
With some randomized lists:
>>> for _ in range(5):
randlist = random.sample(list(range(10)), 7)
print(randlist, missing_num(randlist))
[1, 2, 3, 4, 5, 7, 9] [6, 8]
[0, 1, 2, 5, 6, 7, 8] [3, 4]
[0, 1, 3, 4, 5, 6, 9] [2, 7, 8]
[2, 4, 5, 6, 7, 8, 9] [3]
[0, 2, 3, 4, 5, 7, 8] [1, 6]

Replace values in a list if condition is true

how can I replace the numbers that are greater than 9 by their sum of digits?
right now the list multipliedlist =
[1, 4, 3, 8, 5, 12, 7, 16, 2]
I need to change it to (ex, num 12 and num 16 replaced to (3) and (7) )
[1, 4, 3, 8, 5, 3, 7, 7, 2]
I can use sum(map(int, str(number))) to add the digits but how can i change the values in the same list by their index?
def check_id_valid(id_number):
updatedid = map(int, str(id_number))
multipliedlist = [i * 1 if j % 2 == 0 else i * 2 for j, i in enumerate(updatedid)]
# for index, number in enumerate(multipliedlist):
# if multipliedlist[index] > 9:
# multipliedlist[index] = sum(map(int, str(number)))
# else:
# multipliedlist[index] == number #statement has no effect error.
print(check_id_valid(123456782))
New to python sorry if this is not explained as it's supposed to be
I appreciate any help,Thanks :)
Using a list comprehension
Ex:
data = [1, 4, 3, 8, 5, 12, 7, 16, 2]
print([sum(map(int, str(i))) if i > 9 else i for i in data])
Output:
[1, 4, 3, 8, 5, 3, 7, 7, 2]
Break your task into the constituent parts, namely
replacing a number with the sum of its digits
doing that for a list of numbers.
def sum_digits(number):
# Convert the number into a string (10 -> "10"),
# iterate over its characters to convert each of them
# back to an integer, then use the `sum()` builtin for
# summing.
return sum(int(digit_char) for digit_char in str(number))
def sum_all_digits(numbers):
return [sum_digits(number) for number in numbers]
print(sum_all_digits([1, 4, 3, 8, 5, 12, 7, 16, 2]))
outputs the expected
[1, 4, 3, 8, 5, 3, 7, 7, 2]
To change values by index you can use enumerate() function:
def sum_digits(n):
r = 0
while n:
r, n = r + n % 10, n // 10
return r
multipliedlist = [1, 4, 3, 8, 5, 12, 7, 16, 2]
for i, n in enumerate(multipliedlist):
multipliedlist[i] = sum_digits(multipliedlist[i])
print(multipliedlist)
[1, 4, 3, 8, 5, 3, 7, 7, 2]

Product with descreasing values

I have a 3 lists :
a = [10, 9, 8, 7, 6]
b = [8, 7, 6, 5, 4, 3]
c = [6, 5, 4, 3, 2]
I need to get all the permutations obtained with itertools.product(), BUT only if the values are decreasing:
[10, 8, 6] # is good
[6, 8, 4] # is not good, since 8 > 6
Is there a simple way to do it or should I go with list comprehension and conditions ?
You could do this with a list comprehension by looping over theitertools.product iterator and extracting only those returned items that are sorted in reverse:
[item for item in product(a,b,c) if sorted(item, reverse = True) == list(item)]
Example:
from itertools import product
a = [10,9,8,7,6]
b = [8, 7, 6, 5, 4, 3]
c = [6, 5, 4, 3, 2]
[item for item in product(a,b,c) if sorted(item, reverse = True) == list(item)]
# [(10, 8, 6), (10, 8, 5), (10, 8, 4), (10, 8, 3), (10, 8, 2) ...continues
You can refer following code which does not have list comprehensions:
from itertools import product
a = [10, 9, 8, 7, 6]
b = [8, 7, 6, 5, 4, 3]
c = [6, 5, 4, 3, 2]
for result in product(a,b,c):
if sorted(result, reverse = True) == list(result):
print result
This is a simple one line solution
>>> mylist = [10, 9, 8, 7, 6]
>>> all(earlier >= later for earlier, later in zip(mylist, mylist[1:]))
True
>>> mylist = [10, 9, 7, 8, 6]
>>> all(earlier >= later for earlier, later in zip(mylist, mylist[1:]))
False
I found this here:
Determine if a list is in descending order
If you don't want to use list comprehensions for some reason:
def decreasing(l):
return all(a >= b for a, b in zip(l[:-1], l[1:]))
filter(decreasing, product(a, b, c))

Python operation data List in loop

I want to solve my programming problem, the problem goes like so:
input: 3 #if i input as first input example 3, output is [1, 2, 3]
[1, 2, 3]
input: 2 #2nd input example 2 output is [1, 2] + [1, 2, 3] = [2, 4, 6]
[2, 4, 3]
input: 6 #3rd input [2, 4, 6] + [1, 2, 3, 4, 5, 6] = [3, 6, 6, 4, 5, 6]
[3, 6, 6, 4, 5, 6]
My code:
while True:
a = input('Input : ')
n = range (1,a+1,1)
print n
Outputs:
Input : 3
[1, 2, 3]
Input : 2
[1, 2]
Input : 6
[1, 2, 3, 4, 5, 6]
How can I solve this problem?
Building on your existing code, I would use itertools.izip_longest (Python 2, for 3 use zip.longest):
>>> import itertools
>>> nxt = []
>>> while True:
a = input('Input : ')
n = range(1, a+1, 1) # could change to range(1, a+1)
nxt = map(sum, itertools.izip_longest(n, nxt, fillvalue=0))
print nxt
Which yields:
Input : 3
[1, 2, 3]
Input : 2
[2, 4, 3]
Input : 6
[3, 6, 6, 4, 5, 6]
You can use map
result = []
while True:
a = input('Input : ')
n = range(1, a+1)
result = [(x or 0) + (y or 0) for x,y in map(None, n, result)]
print result
and result would be:
Input : 3
[1, 2, 3]
Input : 2
[2, 4, 3]
Input : 6
[3, 6, 6, 4, 5, 6]
but i can not use external code
Then you can write some code that does exactly what izip_longest does with the zero padding when the new entry is lengthier than the previous result.
The sums are performed in a list comprehension where the values and indices from the input list are gotten by applying enumerate on the entry in the comprehension. Values from the accumulated list are indexed and added to new values at the same index:
tot = []
while True:
a = input('Input : ')
n = range (1,a+1,1)
x, y = len(tot), len(n)
if y > x:
tot[x:y] = [0]*(y-x) # pad the tot list with zeros
tot[:y] = [tot[i]+v for i, v in enumerate(n)]
print tot
Output:
Input : 3
[1, 2, 3]
Input : 2
[2, 4, 3]
Input : 6
[3, 6, 6, 4, 5, 6]
Input : 1
[4, 6, 6, 4, 5, 6]
Input : 0
[4, 6, 6, 4, 5, 6]

Categories