Input in a cycle (Python) - python

I'm learning Python as my first language and now I trying to resolve this problem:
I have to make a loop where I ask the user which elements from a list they want to remove and then remove the elements selected. The loop stops only when the user insert a specific number that corresponds to the length of the list increased by 1 (so I won't have any problem).
I have another problem related to this:
elements_list = ['a','b','c','d']
length_list = len(elements_list)
for i in range(0, length_list):
print (str(i) + str(')') + elements_list[i])
This will print the list starting with 0:
0) a
1) b
2) c
3) d
What do I have to do if I want the list start with 1? (if I use 1 instead of 0 in the range it doesn't print the first element of the list)

In Python, lists can be iterated directly, and enumerate is used to generate indexes. Its optional second parameter gives a starting number:
>>> elements = ['a','b','c','d']
>>> for i,v in enumerate(elements,1):
... print('{}) {}'.format(i,v))
...
1) a
2) b
3) c
4) d
If using Python 3.6+, formatting output is even more simple using f-strings:
>>> elements = ['a','b','c','d']
>>> for i,v in enumerate(elements,1):
... print(f'{i}) {v}')
...
1) a
2) b
3) c
4) d
Refs:
enumerate
str.format
Formatted string literals

One way would be to add a 1 in the range, then subtract a 1 from the index
elements_list=['a','b','c','d']
lenght_list=len(elements_list)
for i in range(1, lenght_list+1):
print (str(i) + str(')') + elements_list[i-1])
Edit: TheoretiCAL's approach is even more straight forward, simply adding 1 to the print statement achieves the same thing.

Related

How to find out if a number is in a list of ranges?

Okay so say I have a list of ranges like
a = [[167772352, 167772415], [167772160, 167772223], [167772288, 167772351], [167772224, 167772255]]
and then I have a number like
b = 167772241
Now I know that b is within the 4th item of the list but how would I check that b is within that in a optimal way? I've thought of using a for loop going through each number of the list and then inserting when the loop breaks but I feel like there has to be some python library function that could handle this? Any suggestion would be welcome!
Simply iterate over the list, take both values and create a range from those values and check if b in range(...), also use enumerate, start it from 1 and you will get in which consecutive range in the list the number is.
a = [[167772352, 167772415], [167772160, 167772223], [167772288, 167772351], [167772224, 167772255]]
b = 167772241
for index, (start, end) in enumerate(a, start=1):
if b in range(start, end + 1):
print(index)
break
You can also use a list comprehension:
a = [[167772352, 167772415], [167772160, 167772223], [167772288, 167772351], [167772224, 167772255]]
b = 167772241
index = [b in range(start, end + 1) for start, end in a].index(True) + 1
print(index)
Also note the end + 1 used in both ranges, that is because the range doesn't include its end value so adding 1 means that the range is inclusive on both sides. Also both methods will get the index that starts from one, which is how you would usually count (1, 2, 3, 4, ...) as you have stated in your question that b should be in the fourth range (which means that you started counting from 1)
You could use map in the following way:
a = [[167772352, 167772415], [167772160, 167772223], [167772288, 167772351], [167772224, 167772255]]
b = 167772241
c = list(map(lambda a_: b in range(a_[0], a_[1] + 1), a))
The output will be a list of booleans that will indicate whether b is contained in each of a's ranges:
out: [False, False, False, True]
map takes two arguments. The first is a function (or a lambda), that it will then apply to each element of the list that you pass as a second parameter. map returns an special object, but you can easily convert it into a list by using list().
You could write a regular function that will check if b is in range, but using a lambda allows you to write the expression in one line. It takes one argument, a_, which will be populated with each element of the list.

Python - Printing 2 array elements for each line

I would like to create a (for) loop that print 2 Array elements for each line. You'll understand better with an example:
array = ["A","B","C","D"]
The output I want is:
A B
C D
How I can do this? Thanks!
There are some good posts earlier to learn more about Python looping of list. Here is a simple way to get what you expected output - regardless of this list has even or odd items.
lst = ['A', 'B', 'C', 'D'] # can add 'E' to try odd number items.
for i, ch in enumerate(lst, 1):
print(ch, end='\t')
if i % 2 == 0: # check to see if it hit the interval threshold?
print() # if you want 3 items in a row, you can change 2 to 3
Output
A B
C D
Iterate through the list and print 2 items with the print command. You can specify 2 as the increment for iterating, and join part of the list, and can handle odd numbers too. The slice of a list goes up to but not including the 2nd number, so slice with i:i+2. At the end of an odd-length list, there will be no 2nd item but the slice won't give an index-out-of-range error:
list1 = ["A","B","C","D","E"]
for i in range(0, len(list1), 2):
print(' '.join(list1[i:i+2]))
to get
A B
C D
E

How to do print in python in specific way

l = ['a1',1,'b1',2,'c1',3]
how to print like below(expected out)
a1 1
b1 2
c1 3
Do I need to do zip function for this? or any other way
Slice with a stride of 2 and zip with an offset slice:
l = ['a1',1,'b1',2,'c1',3]
for a, b in zip(l[::2], l[1::2]):
print(a, b)
A for loop would do the trick (as mentioned in other answers)
But a list comprehension will also work:
[print(str(x[0]) + ' ' + str(x[1])) for x in zip(l[0::2], l[1::2])]
How does this work?
l[0::2] takes every element from l, starting at index 0, until the last element, and with steps of 2 (in other words it takes all the even elements)
l[1::2] takes all the odd elements
zip bundles those into a zip object (iterable tuples) of pairs
the last step is iterating over those and executing the print function for each of them
A for loop will solve the problem:
l = ['a1',1,'b1',2,'c1',3]
for index in range(0, len(l), 2):
print(l[index] + " " + str(l[index+1]))
It starts at index 0 (at "a1") and goes in steps of 2 (jumping to "b1"). The print statement adds an offset of 1 to access the value in between.
Alternatives for the print statement itself, not changing the structure of the code:
print(l[index], str(l[index+1]), sep=" ") # use space as a separator
print(f"{l[index]} {str(l[index+1])}") # use f-string for formatting
For this i would recommend using dictionaries if its possible, i don't know what you are trying to do.
Use them like this:
l = {'a1':1,'b1':2,'c1':3}
for key, value in l.items():
print("{} {}".format(key, value))

Algorithm to concatenate a list of strings in zig-zag fashion

I have the following problem : From a list of strings, i have to take the first letters from all the strings, after (from back to front), i have to take the second letters, after the third letters from front to end and so on.
Example input :
['abcd', 'efgh', 'ijkl', 'mnop']
Output should be :
'aeimnjfbcgkoplhd'
Here I am so far, the first "for" is appending to the array : aeim and cgko
the second "for" is appending to the array: njfb and plhd. Anyway the order is not good, i need aeim + njfb + cgko + plhd
array = []
if len(list_of_strings[0]) % 2 == 0: # if we have strings with even number of letters
for j in range(len(list_of_strings[0]/2)): # range(2) in our example
for i in range(len(list_of_strings)): # range(4) in our example
array.append(list_of_strings[i][j*2])
for j in range(1, len(list_of_strings[0]), 2): # range(1, 4, 2) in our example
for i in range(len(list_of_strings) - 1, -1, -1): # range(3, -1, -1) in our example
array.append(list_of_strings[i][j])
Please help.
Thank you
You can use a simple one-liner using "unzip" (i.e. zip(*a)) and str.join:
a = ['abcd', 'efgh', 'ijkl', 'mnop']
b = ''.join(''.join(t[::1-2*(i%2)]) for i, t in enumerate(zip(*a)))
assert b == 'aeimnjfbcgkoplhd'
join can take a generator expression as an argument, in this case the generator expression is
''.join(t[::1-2*(i%2)]) for i, t in enumerate(zip(*a))
The expression
zip(*a)
unzips the strings in a, i.e. it returns a generator which yields tuples containing all first letters, all second letters, etc. of each string.
The indexing in
t[::1-2*(i%2)]
ensures that we reverse the order of the tuple every 2nd iteration.
EDIT
I benchmarked my one-liner vs. #cs95's answer, and performance of both is the same within error margins. I think in "real code" I'd hence prefer his solution for its higher clarity.
Think of the characters as elements in a 2D array:
a b c d
e f g h
i j k l
m n o p
We want to go in down on odd columns, then up on even columns, so we do something like this:
chars = []
for i in range(len(l[0])):
for w in l[::1 if i % 2 == 0 else -1]:
chars.append(w[i])
print(''.join(chars))
# aeimnjfbcgkoplhd
l[::1 if i % 2 == 0 else -1] will reverse the list for even columns so we're picking characters from the end. This is intuitive but ugly since slicing the list creates a shallow copy. We can do something a little more clever by using a mod to determine whether to iterate in reverse:
chars = []
for i in range(len(l[0])):
for j in range(len(l)) if i % 2 == 0 else reversed(range(len(l))):
chars.append(l[j][i])
print(''.join(chars))
# aeimnjfbcgkoplhd

How to get the number of the list in a list in Python 3?

I am trying to get the number of the nested list that contains the particular number. This is my code:
listo = [[1,2],[3,4,5]]
for x in listo:
if 3 in x:
print(len(x))
What I am trying to get here is the number of the nested list that has 3 in it. My code is returning 3 because I am of the function len, which is only returning the number of items inside the nested list that has the number. The output should be:
2
Since the number 3 is located on the second nested list. The count starts from 1, not 0.
How can I get the proper output?
Use enumerate:
listo = [[1,2], [3,4,5]]
res = next(i for i, sublist in enumerate(listo) if 3 in sublist)
print(res) # -> 1
Note that Python is 0-index languange; the first element on a list has index number 0. That is why the code above returns 1. If you want to get 2, well, just add 1 to that or, ever better, use the optional start parameter of enumerate (enumerate(listo, 1)).
To make the above Error-proof1, you can specify a default value to be returned in case 3 is not on any sublist.
res = next((i for i, sublist in enumerate(listo) if 3 in sublist), 'N\A')
1 next raises StopIteration if it exhausts the iterable without finding something to return, unless a default value is provided.
Use enumerate specifying the start value as 1:
listo = [[1,2],[3,4,5]]
for i, x in enumerate(listo, 1):
if 3 in x:
print(i)
# 2
Use enumerate so as to get the index of the element in the array.
l1 = ["eat","sleep","repeat"]
# printing the tuples in object directly
for ele in enumerate(l1):
print ele
Output:
(0, 'eat')
(1, 'sleep')
(2, 'repeat')
The same can be used for the code above.
listo = [[1,2,3],[4,5]]
for ind,x in enumerate(listo):
if 3 in x:
print(ind)
You can use enumerate. But if you are very new to coding this simple code is good.
Keep an extra variable (count) which will keep track of the index of the current list.
listo = [[1,2],[3,4,5]]
count = 0
for x in listo:
count += 1
if 3 in x:
print(count)
Simply use enumerate(). enumerate() returns a (element count, element) pair:
for count, element in enumerate(listo):
if 3 in element:
print(count + 1)
# Account for one-based indexing

Categories

Resources