Convert list to a particular format [(123, 123), (345,875)..] - python-3.x

I have the following list:
l = [12, 23,54, 67, 87,98,15, 90, 44,81]
I would like to convert them into pairs with parenthesis. Desired output should look like the following:
[(12, 23),(54, 67), (87,98),(15, 90), (44,81)]
What I tried so far?
print('{}'.format(' '.join('({},)'.format(i) for i in l)))
This does not print the list as pairs. How do I solve this?

l = [12, 23,54, 67, 87,98,15, 90, 44,81]
my=[]
for i in range(0,len(l),2):
my.append(tuple(l[i:i+2]))
print(my)

Rather than for i in l, you'd need to use a range to allow you to set an increment by which to step through. range takes 3 arguments - a starting number, an end number, and (optionally; it defaults to 1) an increment.
Something like this:
tuple_list = [(l[i], l[i+1]) for i in range(0, len(l), 2)]

Related

Improving While-Loop with Numpy

I have given the following three variables:
start = 30 #starting value
end = 60 #ending value
slice_size = 6 #value difference per tuble
start and end are row numbers of an array. My goal is to create an array/list of tuples, where each tuples includes as much items as slice_size defines. A little example: If start and end have the above values the first four tuples would be:
[[30,35],[36,41],[42,47],[48,53],...].
But now comes the clue: the first value of the next tuple does not start with the first value before + slice_size, but rather with first value + slice_size/2. So I want something like this:
[[30,35],[33,38],[36,41],[39,44],...].
This list of tuples goes on until end is reached or right before it is reached - so until <=end . The last value of the list is not allowed to pass the value of end. The value of slice_size must of course always be an even number to work properly.
My nooby attempt is done by a while loop:
condition = 0
i = 0
list = []
half_slice = int(slice_size /2)
while condition <= end:
list.append([start+int(slice_size/2)*i,start+((slice_size-1)+i*half_slice)])
condition = start+((slice_size-1)+i*int(slice_size/2))
i += 1
The thing is, it works. However I know this is complete rubbish and I want to improve my skill. Do you have a suggestion how to do it in a couple of code lines?
you must not use list as it is a reserved word
import numpy as np
start = 30 #starting value
end = 60 #ending value
slice_size = 6 #value difference per tuble
l = [[i,j] for i,j in zip(np.arange(start, end, slice_size/2),
np.arange(start + slice_size - 1,
end + slice_size - 1,
slice_size/2)
)
]
print(l)
Output:
[[30.0, 35.0],
[33.0, 38.0],
[36.0, 41.0],
[39.0, 44.0],
[42.0, 47.0],
[45.0, 50.0],
[48.0, 53.0],
[51.0, 56.0],
[54.0, 59.0],
[57.0, 62.0]]
1) Do NOT use list as a variable name. It is a reserved key-word.
2) Not a NumPy solution but you can use list comprehension:
start = 30 #starting value
end = 60 #ending value
slice_size = 6 #value difference per tuble
result = [[current, current + slice_size - 1] for current in range(start, end - slice_size + 2, slice_size // 2)]
print(result)
Output:
[[30, 35], [33, 38], [36, 41], [39, 44], [42, 47], [45, 50], [48, 53], [51, 56], [54, 59]]
This will work for an odd number slice_size as well.

python random lottery number generator game

I have to make a game where like the lottery my program generates 5 random numbers from a list of numbers 1-50 and one additional number from a list of numbers 1-20 and combines them into a final list that reads eg: (20, 26, 49, 01, 11, + 06) where two numbers are never repeated like (22, 11, 34, 44, 01, + 22) <--- this is what I don't want
attached below is the code I have written yet how do I make it so two numbers or more are never repeated and to add the + into my list without the "" signs
input:
import random
a = list(range(1,51))
b = random.randint(1, 20)
temp = []
for i in range(5):
random.shuffle(a)
temp.append(random.choice(a[:5]))
temp.append('+')
temp.append(b)
print(temp)
output:
[14, 12, 3, 16, 23, '+', 9]
You can not add + without the ' around them - they mark the + as string.
Also: you shuffle your list - simply take the first 5 values - they are random and your list does not contain any dupes so you are golden:
nums = list(range(1,51))
random.shuffle(nums)
five_nums = nums[:5]
print(five_nums) # [44, 23, 34, 38, 3]
To simplyfy it, use:
import random
# creates 5 unique elements from 1..50 and adds a + and a [0-19]+1 number
randlist = random.sample(range(1,51),k=5) + ["+", random.choice(range(20))+1]
print(randlist)
Now you got mixed numbers and strings - you can create a combined string by:
print("You drew {} {} {} {} {} {} {}".format(*randlist))
To create a string like
[48, 2, 9, 6, 41, '+', 8]
You drew 48 2 9 6 41 + 8
Doku:
random.sample (draw without putting back)
You can try the following:
import random
randList, run = [], 0
while run < 6:
number = random.randint(1,51)
if number not in randList:
if run == 5:
randList.append('+'+str(number))
break
randList.append(number)
run += 1
print(randList)
You can't have a string in a list without quotes, however, if you were to print every item in the list (using a for loop or join), the quotes wouldn't be there.
This code will generate a list of 7 random numbers
import random
def main():
numbers = []
for num in range(7):
num = random.randrange(50)
numbers.append(num)
print(numbers)
main()
#No repeating numbers and sorted output
import random
picks = int (input("How Many Picks ?: "))
for i in range (picks):
num_list = random.sample(range(1, 45), 5,)
num_list.sort()
joker_num = random.sample(range(1, 20), 1)
print("Lucky Numbers :", num_list, "-", "Joker :", joker_num)
It didn't work because you need to have
import random

Python: Use a for loop to get Nth number out of a list

I need to get every 3rd value out of a list and add it to a new list.
This is what I have so far.
def make_reduced_samples(original_samples, skip):
skipped_list = []
for count in range(0, len(original_samples), skip):
skipped_list.append(count)
return skipped_list
skip is equal to 3
I get the indexes and not the value of the numbers in the list.
It gives me [0,3,6]. Which are the indexes in the list and not the value of the indexes.
The example I am given is:
In this list [12,87,234,34,98,11,9,72], you should get [12,34,9].
I cannot use skipped_list = original_samples[::3] in any way.
You need to append the value of the original_samples array at the index. Not the index (count) itself.
def make_reduced_samples(original_samples, skip):
skipped_list = []
for count in range(0, len(original_samples), skip):
skipped_list.append(original_samples[count])
return skipped_list
The correct, most pythonic, and most efficient way to do that is to use slicing.
lst = [12, 87, 234, 34, 98, 11, 9, 72]
skipped_list = lst[::3]
print(skipped_list) # [12, 34, 9]
If the step does not obey a linear relation (which it does here), then you could use a list-comprehension with enumerate to filter on the index.
skipped_list = [x for i, x in enumerate(lst) if i % 3 == 0]
print(skipped_list) # [12, 34, 9]
One liner:
skipped_list = [j for (i,j) in enumerate(original_samples, start=1) if i % 3 == 0]

Retrieve one value from default dict on python 3

I have a dict which I populate with data using setdefault method as follows:
if date not in call_dict:
call_dict.setdefault(date, [0, 0]).append(0)
else:
call_dict[date][0] += 1
if x[12] != 'ANSWERED':
call_dict[date][1] += 1
call_dict[date][2] = 100*(call_dict[date][1]/call_dict[date][0])
At the end of this process I have a dict which is structured like this:
{'key' : value0, value1, value2}
Then I have to plot only key and value2 (as value2 is a function of the key) but I can't find the way to access this value.
I tried myDict.values() but it did not work (as expected). I would really like to avoid creating another list/dict/anything because of script performance and also to achieve
that I would still have to reach for the value2 which would solve my problem.
Any ideas how to solve this problem?
Sample values of dict:
{'08:23': [45, 17, 37.77777777777778],
'08:24': [44, 15, 34.090909090909086],
'08:25': [46, 24, 52.17391304347826],
'08:48': [49, 19, 38.775510204081634],
You can get them from the dictionary with a list comprehension:
data = { "2018-07-01": [45, 17, 37.77777777777778],
"2018-07-02": [44, 15, 34.090909090909086],
"2018-07-03": [46, 24, 52.17391304347826],
"2018-07-04": [49, 19, 38.775510204081634]}
xy = [(x,data[x][2]) for x in data.keys()] # extract tuples of (date-key, 3rd value)
print(xy)
Output:
[('2018-07-01', 37.77777777777778), ('2018-07-02', 34.090909090909086),
('2018-07-03', 52.17391304347826), ('2018-07-04', 38.775510204081634)]
If you need them for plotting you might want to do:
x,y = zip(*xy)
print(x)
print(y)
Output:
('2018-07-01', '2018-07-02', '2018-07-03', '2018-07-04') # x
(37.77777777777778, 34.090909090909086, 52.17391304347826, 38.775510204081634) # y
and supply those to your plotting library as x and y data.
Doku: zip(*iterables)

Fast bit string generation given indices

Here a is a list, for example [34, 52, 57].
The function takes in this list and creates a bit string of length 64, where every index is a 0 except at the given indices.
So it would look like [0,0,....1,...1,..1,..0,0,0] where only at indices [34, 52, 57] we have ones.
def bit_string_gen(a):
bit_string = []
for key, value in enumerate(range(64)):
if key in a:
bit_string.append(1)
else:
bit_string.append(0)
return bit_string
Is there a better way to do this, maybe using lambda or map or itertools instead of enumerate.
The problem with your approach is that you:
use an if statement for every bit; and
use the in test which can be rather expensive.
A beter method can be:
def bit_string_gen(a):
bit_string = [0]*64
for value in a:
bit_string[value] = 1
return bit_string
So here you iterate only over the values of a, and you set these bits to 1.
Nevertheless it is a bit weird to encode this with a list of ints. A more compact way to do this is to encode this binary on an integer. For instance by using:
def bit_string_gen(a):
bit_string = 0
for value in a:
bit_string |= 1 << value
return bit_string
So in the last case if you set the bits like in your sample input, you obtain:
>>> bin(bit_string_gen([34, 52, 57]))
'0b1000010000000000000000010000000000000000000000000000000000'
>>> hex(bit_string_gen([34, 52, 57]))
'0x210000400000000'
If you're looking for a solution using map/lambda, here's a one-liner:
map(lambda x: 1 if x in [34, 52, 57] else 0, range(0, 64))

Resources