shorthand if else in list comprehension - list-comprehension

This is my code for making half and double of even and odd numbers in a list. I know that it will work with block for loop.
But i want to know why list comprehension didn't work
Thanks in Advance 😀
entry = input('Enter a number list ').split()
#Convert all items to integer
data = [int(x) for x in entry]
print(data)
rslt = [(a/2 if a%2==0 else 2*a) for a in data]
print(data)
OUTPUT :
Enter a number list 3 4 5
[3, 4, 5]
[3, 4, 5]
[Program finished]

you are not printing rslt :) If you make it print rslt, you will get this output:
Enter a number list 1 2 3 4
[1, 2, 3, 4]
[2, 1.0, 6, 2.0]

Related

How I print number of list one forward, back end use python?

I am a try to do for loop print a list of the number one of the forward and other from the back end.
Example: input: [1,2,3,4,5,6,7,8], output: [1,8,2,7,3,6,5]
You can use modulo operator %:
lst = [1, 2, 3, 4, 5, 6, 7, 8]
out = []
for i in range(len(lst)):
out.append(lst[len(lst) - i // 2 - 1 if i % 2 else i // 2])
print(out)
Prints:
[1, 8, 2, 7, 3, 6, 4, 5]
Thank you for asking this question.
You can iterate in half of its range and print list[i] and list[len(list)-i-1].
-1 because backward indexing starts from 1.
box = []
while mylist:
x = mylist.pop(0)
box.append(x)
while mylist:
m = mylist.pop(-1)
box.append(m)
break
return box

Python return specific items from list in same line

I have a list of items from which I need to separate items with specific "key". Let's say I need all items that follow "X" -> the list may look like this: Y1 1-2 X1 3-5 Z1 6-8, Y2 3-5 X2 5-7 Z2 5-9 so I need to take the X "values" that are 3-5 and 5-7. These should be returned this way: 3 4 5 and 5 6 7 and on their own lines so that they can be used in another functions.
I have also tried taking "X"s to its own dictionary but the problem is still the same. I also know about end="" but it does not help me with this.
def get_x_values(list_parameter):
list_of_items = []
list_of_x = []
for i in list_parameter:
i = i.split(' ')
for item in i:
if item != '':
list_of_items.append(item)
for item, next_item in zip(list_of_items, list_of_items[1:]):
if item == 'X':
list_of_x.append(next_item)
for x in list_of_x:
for i in range(int(x[0]), int(x[-1]) + 1):
yield i
When I loop the yield values trough, I get the X values like this:
3
4
5
5
6
7
When I need them this way:
3 4 5
5 6 7
Any help appreciated.
I modified you code, so that it will work.
def get_x_values(list_parameter):
list_of_items = []
for i in list_parameter:
i = i.split(' ')
for item in i:
if item != '':
list_of_items.append(item)
for item, next_item in zip(list_of_items, list_of_items[1:]):
if item == 'X':
range_list = list(range(int(next_item[0]), int(next_item[-1]) + 1))
yield " ".join(str(number) for number in range_list)
lst = ["Y 1-2 X 3-5 Z 6-8", "Y 3-5 X 5-7 Z 5-9"]
result = get_x_values(lst)
for x in result:
print(x)
However, this is not the most elegant solution. But I guess it's easier to understand for you as it's pretty close to your own attempt.
I hope it helps you. Let me know if there are any questions left. Have a nice day!
You need to
split your list (you got it)
put key and value together (you use zip, I use a dict comprehension for that)
split your values into numbers and convert to int
create a range from your int-converted values to fill in missing numbers
for example like so:
# there is a pesky , in your string, we strip it out
inp = "Y1 1-2 X1 3-5 Z1 6-8, Y2 3-5 X2 5-7 Z2 5-9"
formatted_input = [a.rstrip(",") for a in inp.split(" ")]
print(formatted_input)
# put keys and values together and convert values to int-list
as_dict = {formatted_input[a]:list(map(int,formatted_input[a+1].split("-")))
for a in range(0,len(formatted_input),2)}
print(as_dict)
# create correct ranges from int-list
as_dict_ranges = {key:list(range(a,b+1)) for key,(a,b) in as_dict.items()}
print(as_dict_ranges)
# you could put all the above in a function and yield the dict-items from here:
# yield from as_dict_ranges.item()
# and filter them for key = X.... outside
# filter for keys that start with X
for k,v in as_dict_ranges.items():
if k.startswith("X"):
print(*v, sep=" ") # decompose the values and print seperated onto one line
Outputs:
# formatted_input
['Y1', '1-2', 'X1', '3-5', 'Z1', '6-8', 'Y2', '3-5', 'X2', '5-7', 'Z2', '5-9']
# as_dict
{'Y1': [1, 2], 'X1': [3, 5], 'Z1': [6, 8],
'Y2': [3, 5], 'X2': [5, 7], 'Z2': [5, 9]}
# as_dict_ranges
{'Y1': [1, 2], 'X1': [3, 4, 5], 'Z1': [6, 7, 8],
'Y2': [3, 4, 5], 'X2': [5, 6, 7], 'Z2': [5, 6, 7, 8, 9]}
# output for keys X...
3 4 5
5 6 7
You can omit one list conversion if you do not want to print the map(int, ...) values:
as_dict = {formatted_input[a]:map(int,formatted_input[a+1].split("-"))
for a in range(0,len(formatted_input),2)}
Documentation:
range()
map
str.split()
str.rstrip()

To make odd position in list go forward for one step

I found this code from stackoverflow ... and wondering how can I move index position that I want.
I tried to use for loop and [::1]. And by making, len(a)*[0]...I couldn't make it.
Is there any way to fix items on its position in list?
Second, without using method below, is there another way to reorder items in list?
'''
mylist=['a','b','c','d','e']
myorder=[3,2,0,1,4]
'''
a = [1,2,3,4,5,6,7]
b = ((a+a[:0:-1])*len(a))[::len(a)][:len(a)]
[1, 7, 2, 6, 3, 5, 4] <=b
[7, 1, 6, 2, 5, 3, 4] <= the result i want
Thanks in advance.
I'm not sure if this is what you want:
someList = [1,2,3,4,5,6,7]
orderedList = sorted(someList)
reversedOrderedList = orderedList[::-1]
finalList = []
for i in range(len(someList)):
if i % 2 == 0:
finalList.append(reversedOrderedList[i//2])
else:
finalList.append(orderedList[i//2])
print(finalList)
output:
[7, 1, 6, 2, 5, 3, 4]
if so, you can write it in shorter way (without reversedOrderedList):
someList = [1,2,3,4,5,6,7]
orderedList = sorted(someList)
finalList = []
for i in range(len(someList)):
if i % 2 == 0:
finalList.append(orderedList[-1-i//2])
else:
finalList.append(orderedList[i//2])
print(finalList)
and from here you can write it without if statement:
someList = [1,2,3,4,5,6,7]
orderedList = sorted(someList)
for i in range(len(someList)):
finalList.append(orderedList[((-1)**(i%2+1)-1)//2 + ((- 1)**(i%2+1))*(i//2)])
print(finalList)
It is not pretty but after that you can easily write a generator.
Zip the list with its reversed version, flatten it and take the first half:
from itertools import chain
a = [1,2,3,4,5,6,7]
b = list(chain.from_iterable(zip(a[::-1], a)))
print(b[:len(b) // 2])
Output
[7, 1, 6, 2, 5, 3, 4]

Reverse a list to a range

I want to reverse a list to a specific range but I am new to Python and I am doing this. Actually i want to reverse a list but to a specific value and I am trying this.
>>> li = [1,2,3,4,5,6]
>>> li = list(reversed(li))
>>> print (li)
[6, 5, 4, 3, 2, 1]
>>> for i in li(range(0,4,1))
SyntaxError: invalid syntax
>>> for i in li(range(0,4,1)):
print(i)
What output are you trying to get?
If you want the certain parts of the list li[2:] will return [4, 3, 2, 1]
and li[:3] will return [6, 5, 4].
You could use slicing and split the list into two for this.
li = [1,2,3,4,5,6]
final_list = li[:li.index(3)]
final_list = final_list.reverse() + li[li.index(3):]

Returning the N largest values' indices in a multidimensional array (can find solutions for one dimension but not multi-dimension)

I have a numpy array X, and I'd like to return another array Y whose entries are the indices of the n largest values of X i.e. suppose I have:
a =np.array[[1, 3, 5], [4, 5 ,6], [9, 1, 7]]
then say, if I want the first 5 "maxs"'s indices-here 9, 7 , 6 , 5, 5 are the maxs, and their indices are:
b=np.array[[2, 0], [2 2], [ 2 1], [1 1], [0 , 2])
I've been able to find some solutions and make this work for a one dimensional array like
c=np.array[1, 2, 3, 4, 5, 6]:
def f(a,N):
return np.argsort(a)[::-1][:N]
But have not been able to generate something that works in more than one dimension. Thanks!
Approach #1
Get the argsort indices on its flattened version and select the last N indices. Then, get the corresponding row and column indices -
N = 5
idx = np.argsort(a.ravel())[-N:][::-1] #single slicing: `[:N-2:-1]`
topN_val = a.ravel()[idx]
row_col = np.c_[np.unravel_index(idx, a.shape)]
Sample run -
# Input array
In [39]: a = np.array([[1,3,5],[4,5,6],[9,1,7]])
In [40]: N = 5
...: idx = np.argsort(a.ravel())[-N:][::-1]
...: topN_val = a.ravel()[idx]
...: row_col = np.c_[np.unravel_index(idx, a.shape)]
...:
In [41]: topN_val
Out[41]: array([9, 7, 6, 5, 5])
In [42]: row_col
Out[42]:
array([[2, 0],
[2, 2],
[1, 2],
[1, 1],
[0, 2]])
Approach #2
For performance, we can use np.argpartition to get top N indices without keeping sorted order, like so -
idx0 = np.argpartition(a.ravel(), -N)[-N:]
To get the sorted order, we need one more round of argsort -
idx = idx0[a.ravel()[idx0].argsort()][::-1]

Resources