Python multiple loops - python

A = [[[1,2,3],[4]],[[1,4],[2,3]]]
Here I want to find lists in A which sum of all sublists in list not grater than 5.
Which the result should be [[1,4],[2,3]]
I tried a long time to solve this problem in python. But I still can't figure out the right solution, which I stuck at loop out multiple loops. My code as follows, but its obviously wrong, how to correct it?
A = [[[1,2,3],[4]],[[1,4],[2,3]]]
z = []
for l in A:
for list in l:
sum = 0
while sum < 5:
for i in list:
sum+=i
else:
break
else:
z.append(l)
print z
Asking for help~

Simplification of #KindStranger method in a one-liner:
>> [sub for x in A for sub in x if max(sum(sub) for sub in x) <= 5]
[[1, 4], [2, 3]]

A simple solution which you can think of would be like this -
A = [[[1,2,3],[4]],[[1,4],[2,3]]]
r = [] # this will be our result
for list in A: # Iterate through each item in A
f = True # This is a flag we set for a favorable sublist
for item in list: # Here we iterate through each list in the sublist
if sum(item) > 5: # If the sum is greater than 5 in any of them, set flag to false
f = False
if f: # If the flag is set, it means this is a favorable sublist
r.append(list)
print r
But I'm assuming the nesting level would be the same. http://ideone.com/hhr9uq

This should work for your problem:
>>> for alist in A:
... if max(sum(sublist) for sublist in alist) <= 5:
... print(alist)
...
[[1, 4], [2, 3]]

The one with all()
[t for item in A for t in item if all(sum(t)<=5 for t in item)]

Related

How to multiply two sublists within the same list?

I am new to python and SO. I want to multiply each element of lists in a list of lists to another list lying in the same list of lists and compare it with a reference value. This will be more clear with an example:
for L = [[1,2,3,4,5,10],[3,2,4,1,5,10]] ##there can be more than 2 lists in this list of lists
I want only those pairs whose product results in 10.
Out: L = [[1,10],[2,5]]
Edit: I prefer a method without any imports, since I am doing this for building logic and my editor doesn't contain any modules to import. Also, if there are more than 2 lists in a list of lists For eg. there are 3 Lists in a list of lists: then I want triplets for that sake. ANd if 4 lists then I need quadruples.
Here's my code attempt as requested.
N = []
J = []
F = []
Z = []
S = []
O = []
num = input("Enter no. of elements in list")
print ('Enter numbers')
prod = 1
for i in range(int(num)):
n = input("num :")
N.append(int(n))
for x in N:
prod = prod*x
print (prod)
k = int(input("Enter no. of splits:"))
##d = [[] for x in xrange(k)]
##var_dict = []
for o in range(1,prod+1):
if prod%o == 0:
J.append(o)
print (J)
for g in range(k):
O.append(J*(k-1))
print (O)
for a in range(len(O)):
for b in range(len(O)):
if O[i]*O[i+1] == prod:
Z.extend(O)
##Z = [[a, b] for a in J for b in F if a*b == prod] ##imp
print (Z)
for e in Z:
if e not in S and sorted(e) not in S:
S.append(e)
print (S)
You can use itertools.product to find groups of numbers and filter them based on their product
>>> from itertools import product
>>> from functools import reduce
>>> lst = [[1,2,3,4,5,10],[3,2,4,1,5,10]]
>>> ans = [p for p in product(*lst) if reduce(lambda x,y:x*y, p) == 10]
>>> # Remove duplicates
>>> ans = list(map(list, set(map(frozenset, ans))))
>>> print (ans)
[[1, 10], [2, 5]]
>>>
In a comment you say you say you want code without any imports. Importing product from itertools and reduce do simplify and speed the code, but the job can be done without imports. Here is a recursive solution. I am not quite satisfied with this code but it seems to work and passes all my tests. I generalized the problem somewhat so that the input can have tuples or other sequences and not just lists.
def prod_is_target(seq_of_seqs, target):
"""Return a list of lists, where each sublist contains one member
of each input subsequence in order, and the product of those
members equals the target value. If there is no such list possible,
return None. If seq_of_seqs is empty, return an empty list if the
target is 1 and return None otherwise.
"""
if not seq_of_seqs: # if is empty sequence
return [] if target == 1 else None
result = []
for val in seq_of_seqs[0]:
if target % val: # skip if target is not a multiple of val
continue
prodlists = prod_is_target(seq_of_seqs[1:], target // val)
if prodlists is None: # skip if failed with later sublists
continue
if not prodlists: # if is empty list
result.append([val])
else:
for prodlist in prodlists:
result.append([val] + prodlist)
return result if result else None
print(prod_is_target([[1,2,3,4,5,10], [3,2,4,1,5,10]], 10))
The printout from that code is
[[1, 10], [2, 5], [5, 2], [10, 1]]
I'll leave it to you to remove what you consider to be duplicates. I can think of situations where you would want this full list, however.

Python# rearranging array with high and low element in list?

I am new in python i would like to rearranging list with sequence of high and low value. Example Input is a=[1,2,3,4,5] then output should be
a=[5,1,4,2,3].i solved this way any one have better solution? please guide me.Thank you in Advance.
number=int(input("how many number do you want to input?"))
number_list=[]
for i in range(number):
array=int(input())
number_list.append(array)
print(number_list)
# empty array for adding value in list
tmp=[]
i=0
m=len(number_list)
while i<m:
# when last element left in array it will add on our tmp list
if i > len(number_list):
tmp.extend(number_list)
# once all value add in array it will break the program
if len(tmp) == m:
break
else:
high=max(number_list)
low=min(number_list)
tmp.append(high)
tmp.append(low)
#number_list.remove(high)
#number_list.remove(low)
# remove the element after added in the list
number_list.remove(high)
number_list.remove(low)
#print(len(number_list))
#print(tmp)
i +=1
print(tmp)
It is really easy, using a basic for-loop and a helper list. You are overthinking it:
list1 = [1,2,3,4,5]
list1.sort()
resultList = []
for i in range(len(list1)):
resultList.append(list1[len(list1)-1-i])
resultList.append(list1[i])
resultList = resultList[:len(resultList)//2]
list1 = resultList
Now, if you try to print it:
print(list1) # [5, 1, 4, 2, 3]
Note: This only works for Python 3, you have to do minor adjustments for it to work with Python 2 as well
My adea is to combine two lists alternatively b and c, the first is an order descending of list a, and the scond in order ascending of a
import itertools
b=sorted(a, reverse=True)
c=sorted(a)
print [x for x in itertools.chain.from_iterable(itertools.izip_longest(b,c)) if x][:len(a)]
Aother approach using min(), max() and a generator:
# list passed in argument must be sorted
def get_new_list(a):
for k in range(int(len(a)/2)+1):
aa = max(a[k:len(a)-k])
bb = min(a[k:len(a)-k])
if aa != bb:
yield aa
yield bb
else:
yield aa
a = [1,2,3,4,5]
a.sort()
final = list(get_new_list(a))
print(final)
Another approach using for loop and list slicing. This approach is more efficient than using min() and max():
def get_new_list(a):
for k in range(int(len(a)/2)+1):
aa = a[k:len(a)-k]
if len(aa) > 1:
yield aa[-1]
yield aa[0]
else:
yield aa[0]
a = [5,1,2,3,4]
# list must be sorted
a.sort()
final = list(get_new_list(a))
print(final)
Both will output:
[5, 1, 4, 2, 3]

Print a new line in between a list in python

I have a list of potentially unknown length like so:
list = [[1,2], [3,4,5], [6]]
I have a for loop that prints these items out, but I also want to be able to add an extra new line in between.
1
2
3
4
5
6
I don't want an additional new line after the final item or before the first. I have a for loop that prints out spaces in between the items in the line. However, there are instances where 1 or more indices are empty. In that case, I don't want to add an extra new line. I've managed to figure out if the first or last index is empty and how to deal with that, but not a middle index.
For example the above result should also be obtainable with this:
list = [[1, 2], [], [3, 4, 5], [6]]
I'm not sure what's the best way to determine this.
Use enumerate() like this:
for i, sub in enumerate(mylist):
if i: print() # If you are using Python 2, remove the parentheses
for x in sub:
print(x)
Edit: I misunderstood your question a little bit. Since your second example list had invalid syntax, I assumed that meant just two sublists. The comment by PaulRooney has cleared that up, so you can do this:
should_print = False
for sub in mylist:
if should_print: print()
for x in sub:
print(x)
should_print = bool(sub)
Since you don't want extra space before or after it sounds like str.join will probably be closer to what you want then other answers that print it chunk by chunk, first you need some generator for each chunk formatted on its own:
def parse_list(mylist):
for seq in mylist:
if seq: #is not empty
yield "\n".join(map(str,seq))
#with print function
print(*parse_list(stuff), sep="\n\n")
#old print statement (but still forward compatible)
print ("\n\n".join(parse_list(stuff)))
you could also just use a generator expression if you only need to use this once:
each_block = ("\n".join(map(str,seq)) for seq in stuff if seq)
print("\n\n".join(each_block))
Or you could condense this to a single line but I wouldn't:
print("\n\n".join("\n".join(map(str,seq)) for seq in stuff if seq))
list = [[1,2],[], [3],[5,6,7],[8]]
first = True
for item in list:
if first and item:
first = False
for number in item:
print(number)
else:
if item:
print('')
for number in item:
print(number)
list = [[1, 7, 3], [], [7, 10], None, [2, 3, 4]]
for i, v in enumerate(list):
if v:
if i != 0:
print
for x in v:
print x
When you say an index is "empty" do you mean it contains None?
list1 = [[1,2], None, [3]]
Or it contains an empty list?
list1 = [[1,2], [], [3]]
Either way, I think this would work:
for i,j in enumerate(list1):
if j:
for k in j:
print k
if i+1 < len(list1):
print
Edit: The above assumes that your input is always a list of lists, as your question seems to imply.
Comparing the current index to the length of the list to determine whether we're at the end will fail if the list has one or more empty elements at the end, e.g.:
list3 = [[1,2], [], [3], []]
This will output:
(start)
1
2
3
(end)
Note that there's a line break after the 3, which it sounds like you wouldn't want. You'd need some additional logic to account for that, if it's a possibility.
This should do the trick:
for idx, i in enumerate(l):
if i:
for j in i:
print(j)
if idx < len(l) - 1:
print()

how to extract numbers from each position of a python list of lists

I have a list :
N=[[0,3,4], [0,1,2,9,3], [0,3]]
How do i get it so use ths list to get another list with each list item being a number for each positon of the list items in N so that the new list looks like:
newList=[[0,0,0], [3,1,3], [4,2] ,[9], [3]]
so he first item in newList is a sublist that contains the first number in N[0], the first number in N[1], and the first number in N[2]. The next sublist in N will do the same just for the second positions.
Could make use of izip_longest, then filter out the default values, eg:
from itertools import izip_longest
N=[[0,3,4], [0,1,2,9,3], [0,3]]
new_list = [[el for el in items if el is not None] for items in izip_longest(*N)]
# [[0, 0, 0], [3, 1, 3], [4, 2], [9], [3]]
Try the list comprehension
newList= [reduce(lambda x,y: x + [y[i]] if i<len(y) else x, N, [])
for i in range(max(map(len,N)))]
The for just iterates i upto the length of the longest sublist in N, using map with len to construct a temporary list of the lengths of the lists in N to calculate the max length.
The reduce builds up each sublist in the result by picking out the ith element of the corresponding input sublist -- but only if that sublist is long enough.
A weird and inneficient way (but maybe easy to understand would be):
Get maximum length of the lists in N
Iterate all those lists from 0 to that maximum.
If you got an error, that's because your original list (the one that came from N) doesn't have that item
N=[[0,3,4], [0,1,2,9,3], [0,3]]
newList = []
max_items = max([len(lst) for lst in N])
for n_lst in N:
for i in range(max_items):
if len(newList) <= i:
newList.append([])
try:
newList[i].append(n_lst[i])
except IndexError:
pass
print "new List: %s" % newList
Another approach, that maybe makes the code cleaner is initializing newList to a list with 5 items, since the longest list on your matrix N ([0,1,2,9,3]) has 5 elements. That way you know that your result (the newList variable) is going to have 5 lists:
N=[[0,3,4], [0,1,2,9,3], [0,3]]
newList = []
max_items = max([len(lst) for lst in N])
newList=list([] for _ in range(max_items))
for i in range(max_items):
for n_lst in N:
if len(n_lst) > i:
newList[i].append(n_lst[i])
print "new List: %s" % newList
Note that instead of catching an IndexException, you can also check if the len() of the list you're evaluating is > i
EDIT:
Just saw John Clements response (https://stackoverflow.com/a/22901233/289011) which is by far the cleaner.
How about the following:
# original list
N = [[0,3,4], [0,1,2,9,3], [0,3]]
# create a new list of `n` lists (n being the length of the longest sublist in N)
newList = [[] for i in xrange(max([len(l) for l in N]))]
# iterate over each list
# enumerate - use the index to append into correct target list
for l in N:
for i, val in enumerate(l):
newList[i].append(val)
print newList
Yields:
[[0, 0, 0], [3, 1, 3], [4, 2], [9], [3]]
Hope this helps! :)
Here is a solution that does not use list comprehensions, but also does not require a pre-processing step to determine maximum list length.
N = [[0,3,4], [0,1,2,9,3], [0,3]]
newList = []
progress = True
i = 0;
while (progress):
progress = False
sublist = []
for list in N:
if len(list) <= i:
continue
else:
sublist.append(list[i])
progress = True
if not progress:
break
newList.append(sublist)
i = i+1
print(N)
print(newList)

How to get item's position in a list?

I am iterating over a list and I want to print out the index of the item if it meets a certain condition. How would I do this?
Example:
testlist = [1,2,3,5,3,1,2,1,6]
for item in testlist:
if item == 1:
print position
Hmmm. There was an answer with a list comprehension here, but it's disappeared.
Here:
[i for i,x in enumerate(testlist) if x == 1]
Example:
>>> testlist
[1, 2, 3, 5, 3, 1, 2, 1, 6]
>>> [i for i,x in enumerate(testlist) if x == 1]
[0, 5, 7]
Update:
Okay, you want a generator expression, we'll have a generator expression. Here's the list comprehension again, in a for loop:
>>> for i in [i for i,x in enumerate(testlist) if x == 1]:
... print i
...
0
5
7
Now we'll construct a generator...
>>> (i for i,x in enumerate(testlist) if x == 1)
<generator object at 0x6b508>
>>> for i in (i for i,x in enumerate(testlist) if x == 1):
... print i
...
0
5
7
and niftily enough, we can assign that to a variable, and use it from there...
>>> gen = (i for i,x in enumerate(testlist) if x == 1)
>>> for i in gen: print i
...
0
5
7
And to think I used to write FORTRAN.
What about the following?
print testlist.index(element)
If you are not sure whether the element to look for is actually in the list, you can add a preliminary check, like
if element in testlist:
print testlist.index(element)
or
print(testlist.index(element) if element in testlist else None)
or the "pythonic way", which I don't like so much because code is less clear, but sometimes is more efficient,
try:
print testlist.index(element)
except ValueError:
pass
Use enumerate:
testlist = [1,2,3,5,3,1,2,1,6]
for position, item in enumerate(testlist):
if item == 1:
print position
for i in xrange(len(testlist)):
if testlist[i] == 1:
print i
xrange instead of range as requested (see comments).
Here is another way to do this:
try:
id = testlist.index('1')
print testlist[id]
except ValueError:
print "Not Found"
Try the below:
testlist = [1,2,3,5,3,1,2,1,6]
position=0
for i in testlist:
if i == 1:
print(position)
position=position+1
[x for x in range(len(testlist)) if testlist[x]==1]
If your list got large enough and you only expected to find the value in a sparse number of indices, consider that this code could execute much faster because you don't have to iterate every value in the list.
lookingFor = 1
i = 0
index = 0
try:
while i < len(testlist):
index = testlist.index(lookingFor,i)
i = index + 1
print index
except ValueError: #testlist.index() cannot find lookingFor
pass
If you expect to find the value a lot you should probably just append "index" to a list and print the list at the end to save time per iteration.
I think that it might be useful to use the curselection() method from thte Tkinter library:
from Tkinter import *
listbox.curselection()
This method works on Tkinter listbox widgets, so you'll need to construct one of them instead of a list.
This will return a position like this:
('0',) (although later versions of Tkinter may return a list of ints instead)
Which is for the first position and the number will change according to the item position.
For more information, see this page:
http://effbot.org/tkinterbook/listbox.htm
Greetings.
Why complicate things?
testlist = [1,2,3,5,3,1,2,1,6]
for position, item in enumerate(testlist):
if item == 1:
print position
Just to illustrate complete example along with the input_list which has searies1 (example: input_list[0]) in which you want to do a lookup of series2 (example: input_list[1]) and get indexes of series2 if it exists in series1.
Note: Your certain condition will go in lambda expression if conditions are simple
input_list = [[1,2,3,4,5,6,7],[1,3,7]]
series1 = input_list[0]
series2 = input_list[1]
idx_list = list(map(lambda item: series1.index(item) if item in series1 else None, series2))
print(idx_list)
output:
[0, 2, 6]
l = list(map(int,input().split(",")))
num = int(input())
for i in range(len(l)):
if l[i] == num:
print(i)
Explanation:
Taken a list of integer "l" (separated by commas) in line 1.
Taken a integer "num" in line 2.
Used for loop in line 3 to traverse inside the list and checking if numbers(of the list) meets the given number(num) then it will print the index of the number inside the list.
testlist = [1,2,3,5,3,1,2,1,6]
num = 1
for item in range(len(testlist)):
if testlist[item] == num:
print(item)
testlist = [1,2,3,5,3,1,2,1,6]
for id, value in enumerate(testlist):
if id == 1:
print testlist[id]
I guess that it's exacly what you want. ;-)
'id' will be always the index of the values on the list.

Categories