How to select a number without replacement in python - python

So I'm trying to make a mix and match between numbers here is my code
import random
P1 = float(input("Person's name?"))
P2 = float(input("Person's name?"))
P3 = float(input("Person's name?"))
A1 = float(input("Activity?"))
A2 = float(input("Activity?"))
A3 = float(input("Activity?"))
s = (A1, A2, A3)
cool1 = random.sample([A1, A2, A3],1)
cool2 = random.sample([A1, A2, A3],1)
cool3 = random.sample([A1, A2, A3],1)
print ("%s job is %s." %(P1, cool1))
print ("%s job is %s." %(P2, cool2))
print ("%s job is %s." %(P3, cool3))
The problem is that it is randomizing but it keeps repeating numbers like here
**
1.0 job is [4.0].
2.0 job is [5.0].
3.0 job is [4.0].
**
What can I do to make it not repeat.
I'm using python 2.7.12
Also how can I use alphanumerical instead of float only.

Best way to achieve this will be to use random.shuffle (if you want to randomize the original sample list) or random.select (if you want to keep the original sample copy):
Example with random.shuffle:
>>> import random
>>> my_samples = ['A1', 'A2', 'A3']
>>> shuffle(my_samples)
>>> cool1, cool2, cool3 = my_samples
# Random Result: cool1 = 'A3', cool2='A1', cool3='A2'
Example with random.select:
>>> cool1, cool2, cool3 = random.sample(['A1', 'A2', 'A3'], 3)
If you want minimal changes in your solution. You may remove an entry from your samples based on random selection and get next choice from remaining samples like:
>>> import random
>>> cool1 = random.sample(my_samples,1)
>>> my_samples.remove(*cool1)
>>> my_samples
['A1', 'A3']
>>> cool2 = random.sample(my_samples,1)
>>> my_samples.remove(*cool2)
>>> cool3 = random.sample(my_samples,1)
>>> my_samples.remove(*cool3)
>>> my_samples
[]
>>> cool1, cool2, cool3
(['A2'], ['A3'], ['A1'])

write a class to pick a unique element from list
1. permutations finds all unique elements
2. rest can define new data and length of result
from itertools import permutations
class PickOne( object ):
def __init__(self,lst,l):
self.lst = lst
self.visit = set()
self.l = l
self.lenght = self.number(l)
def pick(self):
if len(self.visit) == self.lenght :
print 'run out numbers'
return
res = tuple(random.sample(self.lst,self.l))
while res in self.visit:
res = tuple(random.sample(self.lst,self.l))
self.visit.add( res )
return res
def reset(self,l,lst = None):
if not lst:
lst = self.lst
self.__init__(lst,l)
def number(self,l):
return len( list(permutations(self.lst,l)) )
Example:
a = PickOne([1,2,3,4],1)
>>> a.pick()
(2,)
>>> a.pick()
(1,)
>>> a.pick()
(4,)
>>> a.pick()
(3,)
>>> a.pick()
run out numbers
>>> a.reset(2)
>>> a.pick()
(3, 1)
>>> a.pick()
(3, 4)
>>> a.pick()
(2, 1)

Since you are selecting from a list, then you should delete the entry from the list after each check.
Create your original list, which will be used as needed.
Create a second list from the first to use as you select.
As you choose each element from the list, remove it
Put the chosen element into a list of chosen element.
Python remove method
Parameters
obj -- This is the object to be removed from the list.
Return Value
This method does not return any value but removes the
given object from the list.
Example
The following example shows the usage of remove() method.
#!/usr/bin/python
aList = [123, 'xyz', 'zara', 'abc', 'xyz'];
aList.remove('xyz');
print "List : ", aList
aList.remove('abc');
print "List : ", aList
When we run above program, it produces following result −
List : [123, 'zara', 'abc', 'xyz']
List : [123, 'zara', 'xyz']

You could do this:
cool1, cool2, cool3 = random.sample([A1, A2, A3], 3)
Also how can I use alphanumerical instead of float only.
Have you tried not converting your inputs to float...?

Related

How to make an list if i have to start with A end according to length of data generate list containing [A,B,C...,AA]?

Get stuck at one point.
I have one list containing n elements so according to length,
I have to generate list.
For example i have an list contains 25 element then new list will be [A,B,C,...,Y] and for example list contains 26 elements then [A,B,C,...,Z].
Up to z i can easily get list but now i am getting more than 26 elements.
for example length is 27 then i want these type of list [A,B,C,...,Y,Z,AA].
so, how i am able to get these type of list any suggestion ???
Here is a way to write this with itertools: itr generates an infinite number of combinations, first of length 1, then of length 2, etc. Using islice takes the required number of elements.
from string import ascii_uppercase
from itertools import product, count, islice
itr = ("".join(tup)
# choose number of letters, e.g. 1, 2, 3
for k in count(1)
# choose all tuples of k letters, e.g. (A, ), (B, ), ... (A, A,) ...
for tup in product(ascii_uppercase, repeat=k))
res = list(islice(itr, 28))
you can do something like this:
import string
def letters_list_generator(number):
alphabet_string = string.ascii_uppercase
alphabet_list = list(alphabet_string)
letter_list = []
for i in range(0,number):
multiplier = int(i/26)+1
letter_index = i%26
string_for_list = alphabet_list[letter_index] * multiplier
letter_list.append(string_for_list)
return letter_list
For example you can try this code:
list_1 = ['A', 'B', 'C']
list_2 = ['1', '2', '3']
list_3 = []
for i in range(3):
list_3.append(list_1[i] + list_2[i]
The result is sum = ['A1', 'B2', 'C3']. If you play with the for loop, you can obtain what you want.

Separating strings with lists

I was trying to find a way to separate strings in a project of my called 'Chemistry Calculator'. This project takes strings from an input() and compare it in a list:
substance1 = input('Substance 1: ')
substance2 = input('Substance 2: ')
elements = ['f','o','cl','br','i','s','c']
def affinity_table(element1:str,element2:str,table:list) -> str:
s = element1.lower()
r = element2.lower()
if s in table and r in table:
if table.index(s) < table.index(r):
print(s," will chage with ", r)
else:
print(s," won't change with ", r)
else:
print("Those substances are't in the list")
This code above works well.
So I wanted to have it working with hole substances and not just the element. To do this I need to separate the substance in to parts:
the cations parts
the anions parts.
Then I need to compare them with the list. I noticed that the contains() function showed exactly what I wanted, but only with one comparison.
My question came from:
Is there a way of using the contains() function with more than one string and then separate the string in to where the similarity is found.
Something similar to this:
a = 'NaCO3' #First input.
b = 'KCO3' #Second input.
list = ['Na','K'] #The list.
# Way of separating the values with the list.
# ^ my objective.
a1 = 'Na' #Separation with a.
a2 = 'CO3' #The rest of a.
b1 = 'K' #The rest of b.
b2 = 'CO3' #The rest of b.
# ^ expected outputs from the separation.
if table.index(a1) < table.index(a2):
print(a1,' will change with ', b1, 'and become', a1 + b2)
else:
print(a1," won't change with ", b1, 'and will stay normal')
# ^ the list index comparison from the 1st code.
#After the solution, here are the results:
Disclaimer
Just to be clear: for the constrained scope of what you are doing this solution might be applicable. If you want to parse any chemical compound (and those can look quite complicated) you need a full fledged parser, not the toy regex solution I came up with.
Here's an idea:
Dynamically build a regex with elements from your list as alternating matching groups. (re.split keeps groups when splitting.)
>>> import re
>>> lst = ['Na', 'K']
>>> regex = '|'.join('({})'.format(a) for a in lst)
>>> regex
>>> '(Na)|(K)'
Apply the regex...
>>> re.split(regex, 'NaCO3')
>>> ['', 'Na', None, 'CO3']
>>> re.split(regex, 'KCO3')
>>> ['', None, 'K', 'CO3']
... and filter out falsy values (None, '')
>>> list(filter(None, re.split(regex, 'NaCO3')))
>>> ['Na', 'CO3']
>>> list(filter(None, re.split(regex, 'KCO3')))
>>> ['K', 'CO3']
You can assign to those values with extended iterable unpacking:
>>> b1, b2, *unexpected_rest = filter(None, re.split(regex, 'KCO3'))
>>> b1
>>> 'K'
>>> b2
>>> 'CO3'
If you want to bias the split in favor of longer matches, sort lst in descending order first.
Not good:
>>> lst = ['N', 'Na', 'CO3']
>>> regex = '|'.join('({})'.format(a) for a in lst)
>>> list(filter(None, re.split(regex, 'NaCO3')))
>>> ['N', 'a', 'CO3']
Better:
>>> lst = ['N', 'Na', 'CO3']
>>> lst = sorted(lst, key=len, reverse=True)
>>> regex = '|'.join('({})'.format(a) for a in lst)
>>> list(filter(None, re.split(regex, 'NaCO3')))
>>> ['Na', 'CO3']
Let me know if that works for you.

How to print this pattern using Tuples?

I am new to Python Tuples, and doing a learning exercise on the same. How should I print the following pattern when the input is the String HI,HELLO,WELCOME.
(('HI', 'HELLO', 'WELCOME'),)
((('HI', 'HELLO', 'WELCOME'),),)
(((('HI', 'HELLO', 'WELCOME'),),),)
My Attempt
n = input()
arr = tuple(raw_input().split())
arr1 = list()
print arr
while(n>0) :
print(tuple(arr,))
n -= 1
just define (or create) a tuple at start, then nest it on itself (reusing the same variable):
n = 3
arr = ('HI','HELLO','WELCOME') # or tuple(raw_input().split())
while(n>0):
arr = (arr,) # that's enough to create a tuple inside the tuple
print(arr)
n -= 1
result:
(('HI', 'HELLO', 'WELCOME'),)
((('HI', 'HELLO', 'WELCOME'),),)
(((('HI', 'HELLO', 'WELCOME'),),),)
Just nest your first tuple in another tuple each iteration.
>>> n = 3
>>> tup = ('HI', 'HELLO', 'WELCOME')
>>> for _ in range(n):
tup = tup,
print(tup)
(('HI', 'HELLO', 'WELCOME'),)
((('HI', 'HELLO', 'WELCOME'),),)
(((('HI', 'HELLO', 'WELCOME'),),),)
>>>
As you can see, on each iteration the tuple is nested a level deeper. The problem with your original method is that you didn't reassign the new nested tuple back to arr, so your tuple's never nested.
In your attempt you were always printing the same thing. You need to update the tuple on each iteration, so you have to have
while n>0:
arr = (arr,)
print(arr)
n=-1

Basic list operations using python

These three functions are apart of my study guide and would greatly appreciate some assistance.
In each case, the function returns a value (so use the return statement): it does not print the value (no print statement) or mutate (change the value of) any of its arguments.
1) The repl function takes three arguments:
◦old is any value;
◦new is any value;
◦xs is a list.
Example:
>>> repl('zebra', 'donkey', ['mule', 'horse', 'zebra', 'sheep', 'zebra'])
['mule', 'horse', 'donkey', 'sheep', 'donkey']
It returns a new list formed by replacing every occurrence of old in xs with new.
It must not mutate the list xs; i.e., after return from the function, the actual argument given for xs must be what it was before.
>>> friends = ['jules', 'james', 'janet', 'jerry']
>>> repl('james', 'henry', friends)
['jules', 'henry', 'janet', 'jerry']
>>> friends
['jules', 'james', 'janet', 'jerry']
2) The search function looks for a value in a list. It takes two arguments:
◦y is the value being searched for.
◦xs is the list being searched in.
It returns the index of the first occurrence of y in xs, if it occurs; −1 otherwise.
Examples:
>>> words = ['four', 'very', 'black', 'sheep']
>>> search('four', words)
0
>>> search('sheep', words)
3
>>> search('horse', words)
-1
3) The doubles function is given a list of numbers and returns a new list containing the doubles of every number in the given list.
Example:
>>> doubles([1, 3, 7, 10])
[2, 6, 14, 20]
It must not mutate the given list:
>>> salaries = [5000, 7500, 15000]
>>> doubles(salaries)
[10000, 15000, 30000]
>>> salaries
[5000, 7500, 15000]
This is to be done without using any list methods except append. (In particular, you may not use the index or count for the search function.)
Although you can use the list len function, and the list operations +, *, indexing, slicing, and == for comparing lists or elements. You will need to use some of these but not all.
Any help is greatly appreciated like I mentioned in the introduction.
So far all I have is.
def repl (find, replacement, s):
newString = ''
for c in s:
if c != find:
newString = newString + c
else:
newString = newString + replacement
return newString
def search(y, xs):
n = len(xs)
for i in range(n):
if xs[i] == y:
return i
return -1
and....
def search(key,my_list):
if key in my_list:
return my_list.index(key)
else:
return
I'm not sure what needs to be returned after the else statement.
def relp(old,new,my_list):
final = []
for x in my_list:
if x is old:
final.append(new)
else:
final.append(x)
return final
def search(key,my_list):
if key in my_list:
return my_list.index(key)
else:
return -1
def doubles(my_list):
return[x*x for x in my_list]
I suspect this lesson is about list comprehensions
doubles = lambda my_list: [x*2 for x in my_list]
repl = lambda old_t,new_t,my_list: [x if x != old_t else new_t for x in my_list]
print repl("cow","mouse",["cow","rat","monkey","elephant","cow"])
print doubles([1,2,3,4,'d'])

List order manipulating in Python

I have two python lists as follow:
ListA = [a1,a2,a1,a3,a2,a4,a5,a4]
ListB = [b1,b2,b1,b3,b2,b4,b5,b4]
What I want is to find the equal elements in the two lists and print them in a file. I have found the equal elements in lists and add them to two new lists as follow:
[a1,a2,a4]
[b1,b2,b4]
I want to compare some parameters with elements in ListA and if an element in ListA and the parameter is equal print the corresponding element in ListB. I do this as follow.
for i,j in enumerate(ListA):
if j == paramname:
filelines.append('%sTransferSourceName = "%s"\n'%(indent,ListB[i]))
My problem is that the element are not in the order for ListB. It is added like below:
b2,b4,b1
So the whole order get mixed up.
Note that the number of letters in each element in the lists may differ.
Here is the code I have done so far:
def ProcessLinks():
duplicates = [x for x in linkparamArray if linkparamArray.count(x) > 1]
linkstemp = list(set(duplicates))
for i in linkstemp:
links.append(i)
def ProcessLinks2():
duplicates2 = [x for x in linkparameterArray if linkparameterArray.count(x) > 1]
linkstemp2 = list(set(duplicates2))
for j in linkstemp2:
linkparameters.append(j)
And here is the comparing code:
paramname = a1
for i,j in zip(linkparameters,links):
if i == paramname:
filelines.append('%s TransferSourceName = "%s"\n(indent,j))
You can use collections.Counter to determine duplicate elements.
>>> ListA = ['a1','a2','a1','a3','a2','a4','a5','a4']
>>> ListB = ['b1','b2','b1','b3','b2','b4','b5','b4']
>>> cB=collections.Counter(ListB)
>>> cA=x=collections.Counter(ListA)
>>> [i for i in cA if cA[i]>1]
['a1', 'a2', 'a4']
>>> [i for i in cB if cB[i]>1]
['b4', 'b1', 'b2']
As per the Comment of OP as the order is important than the following solution might work using (OrderedDict)[http://docs.python.org/library/collections.html#collections.OrderedDict]
dB=collections.OrderedDict()
dA=collections.OrderedDict()
>>> for a in ListB:
dB.setdefault(a,0)
dB[b]+=1
>>> for b in ListB:
dB.setdefault(b,0)
dB[b]+=1
>>> [i for i in dA if dA[i]>1]
['a1', 'a2', 'a4']
>>> [i for i in dB if dB[i]>1]
['b1', 'b2', 'b4']
By 'equal elements' do you mean repeated elements?
What is 'indent'?
The problem with using a dictionary is that you cannot have keys that are repeated. So if you were to build a dictionary using the two lists, the dictionary will contain only one entry (key, value pair) for each element in a list that is repeated.

Categories

Resources