Python 3.x random input for lists - python-3.x

from random import randint
List = [randint(0,99)*20]
print(List)
How could i go along the lines of make it into a list for 20 different random numbers between 0 and 99? The code i have ends up multiplying one random number 20 times.

You can use list comprehension:
List = [randint(0,99) for i in range(20)]

from random import randint
List = [randint(0,99) for i in range(20)]
print("%3s" % List)
List.sort()
print("%3s" % List)
My primary is Java. I hope this helps!

Related

faster method for comparing two lists element-wise

I am building a relational DB using python. So far I have two tables, as follows:
>>> df_Patient.columns
[1] Index(['NgrNr', 'FamilieNr', 'DosNr', 'Geslacht', 'FamilieNaam', 'VoorNaam',
'GeboorteDatum', 'PreBirth'],
dtype='object')
>>> df_LaboRequest.columns
[2] Index(['RequestId', 'IsComplete', 'NgrNr', 'Type', 'RequestDate', 'IntakeDate',
'ReqMgtUnit'],
dtype='object')
The two tables are quite big:
>>> df_Patient.shape
[3] (386249, 8)
>>> df_LaboRequest.shape
[4] (342225, 7)
column NgrNr on df_LaboRequest if foreign key (FK) and references the homonymous column on df_Patient. In order to avoid any integrity error, I need to make sure that all the values under df_LaboRequest[NgrNr] are in df_Patient[NgrNr].
With list comprehension I tried the following (to pick up the values that would throw an error):
[x for x in list(set(df_LaboRequest['NgrNr'])) if x not in list(set(df_Patient['NgrNr']))]
Though this is taking ages to complete. Would anyone recommend a faster method (method as a general word, as synonym for for procedure, nothing to do with the pythonic meaning of method) for such a comparison?
One-liners aren't always better.
Don't check for membership in lists. Why on earth would you create a set (which is the recommended data structure for O(1) membership checks) and then cast it to a list which has O(N) membership checks?
Make the set of df_Patient once outside the list comprehension and use that instead of making the set in every iteration
patients = set(df_Patient['NgrNr'])
lab_requests = set(df_LaboRequest['NgrNr'])
result = [x for x in lab_requests if x not in patients]
Or, if you like to use set operations, simply find the difference of both sets:
result = lab_requests - patients
Alternatively, use pandas isin() function.
patients = patients.drop_duplicates()
lab_requests = lab_requests.drop_duplicates()
result = lab_requests[~lab_requests.isin(patients)]
Let's test how much faster these changes make the code:
import pandas as pd
import random
import timeit
# Make dummy dataframes of patients and lab_requests
randoms = [random.randint(1, 1000) for _ in range(10000)]
patients = pd.DataFrame("patient{0}".format(x) for x in randoms[:5000])[0]
lab_requests = pd.DataFrame("patient{0}".format(x) for x in randoms[2000:8000])[0]
# Do it your way
def fun1(pat, lr):
return [x for x in list(set(lr)) if x not in list(set(pat))]
# Do it my way: Set operations
def fun2(pat, lr):
pat_s = set(pat)
lr_s = set(lr)
return lr_s - pat_s
# Or explicitly iterate over the set
def fun3(pat, lr):
pat_s = set(pat)
lr_s = set(lr)
return [x for x in lr_s if x not in pat_s]
# Or using pandas
def fun4(pat, lr):
pat = pat.drop_duplicates()
lr = lr.drop_duplicates()
return lr[~lr.isin(pat)]
# Make sure all 3 functions return the same thing
assert set(fun1(patients, lab_requests)) == set(fun2(patients, lab_requests)) == set(fun3(patients, lab_requests)) == set(fun4(patients, lab_requests))
# Time it
timeit.timeit('fun1(patients, lab_requests)', 'from __main__ import patients, lab_requests, fun1', number=100)
# Output: 48.36615000000165
timeit.timeit('fun2(patients, lab_requests)', 'from __main__ import patients, lab_requests, fun2', number=100)
# Output: 0.10799920000044949
timeit.timeit('fun3(patients, lab_requests)', 'from __main__ import patients, lab_requests, fun3', number=100)
# Output: 0.11038020000069082
timeit.timeit('fun4(patients, lab_requests)', 'from __main__ import patients, lab_requests, fun4', number=100)
# Output: 0.32021789999998873
Looks like we have a ~150x speedup with pandas and a ~500x speedup with set operations!
I don't have a pandas installed right now to try this. But you could try removing the list(..) cast. I don't think it provides anything meaningful to the program and sets are much faster for lookup, e.g. x in set(...), than lists.
Also you could try doing this with the pandas API rather than lists and sets, sometimes this faster. Try searching for unique. Then you could compare the size of the two columns and if it is the same, sort them and do an equality check.

Python Lists - find uncommon elements

I want to compare two lists in order to create a new list of specific elements found in one list but not in the other. I want the code to return all occurrences of unmatched values.
input:
list1=7,7,8,9
list2=8,9
desired output= 7,7
import numpy as np
list1 = input("Input list1 : ").split(",")
list2 = input("Input list list2 : ").split(",")
main_list = np.setdiff1d(list1,list2)
print(main_list)
You could do:
[i for i in list1 if i in (set(list1) - set(list2))]
using numpy:
import numpy as np
np.array(list1)[np.in1d(list1, np.setdiff1d(list1, list2))].tolist()

oneliner using reduce in python

I'm trying to take my Python skills (beginner) to the next level.
and I'm trying to teach myself the functools.reduce() function
So I'm running every time into the same error;
I'd appreciate if someone could explain to me what is the problem in my code
I'm trying to build a simple func that receive a number and return the sum of number digits
import functools
def sum_using_reduce(number):
return str(number)[0] + str(number)[1]
number = 104
print(functools.reduce(sum_using_reduce, number))
Try this:
number = 104
functools.reduce(lambda x, y: x+y, [int(i) for i in str(number)])
Output: 5
Using your example:
import functools
def sum_using_reduce(x, y) -> int:
return x + y
print(functools.reduce(sum_using_reduce, [int(i) for i in str(105)]))
Output: 6
Another approach:
import functools
def sum_using_reduce(number: int) -> int:
return functools.reduce(lambda x, y: x+y, [int(i) for i in str(number)])
print(sum_using_reduce(124))
Output: 7
In your sum_using_reduce function you are trying to sum two strings, which would simply perform concatenation. Moreover, you are providing an integer as the second argument to the reduce function, where the reduce function requires an iterable to be provided.
Below is a solution that fixes both these requirements:
from functools import reduce
number=104
print(reduce(lambda x,y:x+y,map(int,str(number))))
map(int,str(number)) transforms the number to a string (104->"104") and then turns every character in the string to an integer, returning an iterable map object ("104"->[1,0,4]).
lambda x,y:x+y is a function which takes two integers and sums them.

To generate all possible combinations of items in a list and STORE them in different lists, and to access them later. I have stated an example below

# To generate possible combinations
from itertools import combinations
main_list=('a1','a2','a3','a4')
abc=combinations(main_list,3)
for i in list(abc):
print(i)
# Creating number of empty lists
n=6
obj={}
for i in range(n):
obj['set'+str(i)]=()
# I want to combine these, take list1 generated by combinations and store them down in set1.
/* To generate all possible combinations of items in a list and STORE them in different lists. Eg: main_list=('a1','a2','a3'), now i want to combination lists like set1=('a1'), set2=('a2'), set3=('a3'), set4=('a1','a2'), set5=('a1','a3'), set6=('a2','a3'), set7=('a1','a2','a3'). How to access lists set1, set2,... */
If I understand correctly, you want to generate the power set - the set of all subsets of the list. Python's itertools package provides a nice example function to generate this:
from itertools import chain, combinations
def powerset(iterable):
"powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
s = list(iterable)
return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
While Nathan answers helps with first part of the question, my code will help you making a dictionary, so you can access the sets like sets['set1'] as asked.
from itertools import chain, combinations
def powerset(iterable):
"powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
s = list(iterable)
return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
def make_dict(comb):
sets = {}
for i, set in enumerate(comb):
sets['set'+str(i)] = set
return sets
if __name__ == '__main__':
sets = make_dict(powerset(['a1','a2','a3','a4']))
print(sets['set1'])
Output
('a1',)

Python 2d Array Input using Maps and Split

How to take input into python 2d array using map and split because in competitive coding competition the inputs are given with space?
Is it the correct way to use?
a = numpy.empty((N,M))
for i in range(N):
b=list(map(int,input().split()))
a.append(b)
a.append('\n')
The original question is a bit confused. If you want to store it in a numpy array, I'd be inclined to use np.genfromtxt:
import io
import numpy as np
input = b"""\
1 2 3 4
5 6 7 8"""
if __name__ == '__main__':
print(np.genfromtxt(io.BytesIO(input)))
If, on the other hand, you want to store it in a list of list (although I can't see why this is preferable to a numpy array), this sort of approach should work:
import io
input = b"""\
1 2 3 4
5 6 7 8"""
if __name__ == '__main__':
list_of_lists = [[int(elt) for elt in line.split()] for line in io.BytesIO(input)]
print(list_of_lists)

Resources