meaning of ",0" at the end - python

When I remove the ",0" it throws error and when it is there it shows the right output. I want to know the use of it.
import sys
from collections import Counter
input()
socks,pairs = Counter(map(int,input().strip().split())),0
for s in socks:
pairs = pairs + socks[s] // 2
print(pairs)

You're assigning to two variables (socks and pairs) in this line:
socks,pairs = Counter(map(int,input().strip().split())),0
If you omit ,0, it's like writing:
socks = Counter(map(int,input().strip().split()))
pairs =
Hence the error.

This:
socks, pairs = Counter(map(int,input().strip().split())), 0
translates to this:
(socks, pairs) = (Counter(map(int,input().strip().split())), 0)
It's as if you wrote :
socks = Counter(map(int,input().strip().split()))
pairs = 0
The difference being right side is fully evaluated before assignments, but it doesn't matter here
But the sizes of tuples must match. When you omit ,0 it becomes:
(socks, pairs) = (Counter(map(int,input().strip().split())), )
As you can see, the sizes don't match. This is what causes the problem.

This is called a tuple assignment. for example, if you want to initiate two variables x and y and assign two values a and b for them you can do it with like:
x = a
y = b
or just:
x, y = a, b
in this case, the first value 'a' will be assigned to the first variable 'x' and the second value 'b' will be assigned to the second variable 'y'. In this is very powerful to swap two values without using a temp variable as follows:
x, y = y, x
in your case you are initiating two variables: socks and pairs so they must be followed by two values. In your case:
socks = Counter(map(int, input().strip().split()))
pairs = 0
So, it's pretty obvious that you can't assign one value to two variables. so you can't remove the 0 (pairs initial value) which is a reserved variable to accumulate on it while looping.

Related

Python rearrange a list without changing the values and making every rearrangment different

I want to write a function that get two integers. The integers indicate how many strings of either of the two chars appears in a string.
For example:
my_func(x,y): x amount of 'u' and y amount of 'r'.
my_func(2,3) is a string 'uurrr'
And the goal of the function is to write all the possible combinations of that string without changing the amount of x,y and every rearrangement is different:
Example:
my_func(1,1) will return: 'ru', 'ur'
my_func(1,2) will return: 'urr', 'rur', 'rru'
my_func(2,2) will return: 'uurr', 'ruru', 'rruu','urur', 'ruur', 'urru'
What I tried without covering all cases:
RIGHT = 'r'
UP = 'u'
def factorial(m):
if m>1:
return factorial(m-1)*m
else:
return 1
def binom(n,k):
return int(factorial(n)/(factorial(k)*factorial(n-k)))
def up_and_right(n, k, lst):
if n-k == 1 or n-k==-1 or n-k == 0 or n==1 or k==1:
num_of_ver = n+k
else:
num_of_ver = binom(n+k,2)
first_way_to_target = RIGHT*n + UP*k
lst.append(first_way_to_target)
way_to_target = first_way_to_target
for i in range(num_of_ver-1):
for j in range(n+k-1,0,-1):
if way_to_target[j]==UP and way_to_target[j-1]==RIGHT:
way_to_target = list(way_to_target)
way_to_target[j-1] = UP
way_to_target[j] = RIGHT
way_to_target = ''.join(way_to_target)
lst.append(way_to_target)
return lst
Thanks in advance!
Use itertools.permutations to get all the rearrangements, make a set of them to eliminate duplicates (because e.g. swapping two rs around counts as a separate permutation but doesn't change anything), and then join them back into strings because permutations returns character tuples instead.
This demonstration at the REPL should give you enough to write your function:
>>> import itertools
>>> [''.join(p) for p in set(itertools.permutations('u' * 2 + 'r' * 2))]
['uurr', 'ruur', 'ruru', 'rruu', 'urur', 'urru']

Why last element is not compared in List using zip() in python?

I am using build-in function zip() to compare 2 element in List.
myList =[11,12,93,14,15,45,56,67,78,11]
z = 0;
final = 0 ;
for x, y in zip(myList, myList[1:]):
if x > y :
z = x
if (final<x):
final = x;
print final;
For this code I get valid answer as: 93
Now if I add another element in last index as 333
myList =[11,12,93,14,15,45,56,67,78,11,333]
z = 0;
final = 0 ;
for x, y in zip(myList, myList[1:]):
if x > y :
z = x
if (final<x):
final = x;
print final;
I get still get output as :93 , but the correct answer in 333.
Can someone explain the logic as where I am wrong.
zip stops at the end of its shortest argument. myList[1:] is always one shorter than myList (provided the list isn't empty), and so the last pair you get from zip is x,y = 11,333:
>>> myList =[11,12,93,14,15,45,56,67,78,11,333]
>>> pairs = zip(myList, myList[1:])
>>> list(pairs)[-1]
(11, 333)
But you only ever assign final and z to the current value of x, which can never be the last element. You could add a phantom element to the end of the list that can't trigger the conditions: you're using mixed greater and lesser comparisons, so your best option is the special value "not a number" float('nan'), which is neither bigger nor smaller than any number (all comparisons return False). For the special case of pairs, you can put the dummy element in like this since the second argument is known to be exactly one element shorter than the longer one:
>>> pairs = zip(myList, myList[1:]+[float('nan')])
>>> list(pairs)[-1]
(333, nan)
But for a more general solution, you will want to use zip_longest from itertools, which effectively pads the end of the shorter arguments like this until they are the length of the longest one:
>>> pairs = it.zip_longest(myList, myList[1:], fillvalue=float('nan'))
>>> list(pairs)[-1]
(333, nan)
Take a look at itertools.izip_longest, as you are attempting to zip together iterables that are different in length. izip_longest will allow you to add a fill value for the iterables that are shorter than the longest one.
The reason this happens is because zip has length equal to the shortest sequence. Note that in the first case your list is of even length (so all pairs are returned), but in the second, it's odd, so you don't get the last one. If you wanted different behavior, take a look at itertools.izip_longest.

Setting variable to only equal even numbers, and the other to odds

I'm having trouble trying to split a list into even and odd numbers with the variables odd and even representing their respective numbers.
The professor noted that this line of code:
odd, even = foo([1,2,3,4,5,6], lambda x : x % 2 == 0)
Should split the numbers into odd and even. How do I do something like this? I know how to filter between odd and even numbers, but I'm unsure of how to set two variables in one line equal to their respective parts.
In your example foo is a function, and returns a pair of variables. For example:
def foo():
a = 1
b = 2
return (a, b)
x, y = foo() # x is now '1', and y is now '2'
So you need to create a function that iterates over the input list, and assigns the elements to either an odd list or an even list. Then return both of these lists, as the above example.
Return a tuple containing the odd values and the even values. The nearest your function could go it is:
>>> def foo(l,f):
... even = filter(f,l)
... odd = [i for i in l if i not in even]
... return odd,even
...
>>> odd, even = foo([1,2,3,4,5,6], lambda x : x % 2 == 0)
>>> odd
[1, 3, 5]
>>> even
[2, 4, 6]
This assignment is known as Tuple Unpacking. In this way when you return comma separated variables and the same number of variables on the left hand side, each of the variables on the left hand side will be respectively assigned to those on the right hand side.

Select lists depending on an item they contain

So, I'm trying to create a sudoku solver. Now, I want to check if a number is in it's line, column and square. Can I do it without introducing the line, column and square as function parameters? Is there any way to select the lists that contain an item? Here's my code:
sudoku = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
line1 = [sudoku[0],sudoku[1],sudoku[2],sudoku[3]]
column1 = [sudoku[0],sudoku[4],sudoku[8],sudoku[12]]
square1 = [sudoku[0],sudoku[1],sudoku[4],sudoku[5]]
def sudoku_cellsolver(x):
while sudoku[x] == 0:
number = sudoku[x]+1
if number not in #"List, column, square":
sudoku[x] = number
else:
number = number + 1
#Check another time, etc
while sudoku[x] != 0:
sudoku_cellsolver(x+1)
Any help welcomed. I also have an error when the second branch gets out of range, but I will deal with it later.
EDIT:
Pseudocode:
sudoku = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
l1 = {sudoku[0],sudoku[1],sudoku[2],sudoku[3]} #Converted to set
c1 = {sudoku[0],sudoku[4],sudoku[8],sudoku[12]} #Converted to set
sq1 = {sudoku[0],sudoku[1],sudoku[4],sudoku[5]} #Converted to set
group0 = [l1 | c1 | sq1] #Concatenation of sets
def sudoku_cellsolver(x,group):
if sudoku[x] == 0:
number = sudoku[x]+1
if number not in group:
sudoku[x] = number
The main problem is that I can't use a loop to solve one gap after another because I can't modify the parameter "group0" so that it changes to "group1" inside the function, something I can do with "sudoku[0]" to "sudoku[1]" using the "sudoku[x] = sudoku[x+1]".
If there's no way to change from "group0" to "group1" from inside the function, I'll have to define 16 almost-equal functions where only the "group" changes, and executing them from another function that uses an "if" statement to decide which one of the 16 functions is executed.
Your line1, column1, and square1 variables look like they're defined at the global level, so you should be able to access them like any other variable. You're on the right track with the if thing not in list construct. Try concatenating the lists together to build one list that you can check for membership:
if number not in line1 + column1 + square1:
sudoku[x] = number
This won't work for you if you need to be able to determine which of those lists number is in, but it doesn't look like you wanted to do that anyway.
If you want to modify your globals within a function, you will need to use the global keyword as described in this SO answer.
EDIT (based on comments)
It now appears that you're looking for the zip() function. Zip() groups elements from multiple iterables together by their index. Example:
a = [1,2,3]
b = [4,5,6]
c = [7,8,9]
groups = zip(a, b, c)
for i in xrange(3):
print(groups[i])
Outputs this:
(1, 4, 7)
(2, 5, 8)
(3, 6, 9)
Can you use zip() to group your elements together?

Variable nesting in Python

Basically, I need to make my program able to create multiple (unlimited) variables for me, that I will still be able to use manipulate through my code, without me defining them.
I was thinking to have a letter and a number as the variable name, such as a1, and have the program create new variables just adding 1 to the number. So it would create a1 through a30 or so. How would I do this?
My program is going to add polynomials and the variables (or list now) is to separate the different monomials, and since I don't know how many monomials there will be in the polynomial, I needed a way to make the number flexible so I have an exact amout of spaces for the monomials, no extras, and no less.
Here's the code:
# Sample polynomial set to x, the real code will say x = (raw_input("Enter a Polynomial")).
x = '(5xx + 2y + 2xy)+ (4xx - 1xy)'
# Isdigit command set to 't' to make the code easier to write.
t = str.isdigit
# Defining v for later use.
v = 0
# Defining 'b' which will be the index number that the program will look at.
b = 1
# Creating 'r' to parse the input to whatever letter is next.
r = x [b]
# Defining n which will be used later to tell if the character is numeric.
n = 0
# Defining r1 which will hold one of the monomials, ( **will be replaced with a list**)
#This was the variable in question.
r1 = ''
# Setting 'p' to evaluate if R is numeric ( R and T explained above).
p = t(r)
# Setting 'n' to 1 or 0 to replace having to write True or False later.
if p == True:
n = 1
else:
n = 0
# Checking if r is one of the normal letters used in Algebra, and adding it to a variable
if r == 'x':
v = 'x'
c = 1
elif r == 'y':
v = 'y'
c = 1
elif r == 'z':
v = 'z'
c = 1
# If the character is a digit, set c to 0, meaning that the program has not found a letter yet (will be used later in the code).
elif n == 1:
v = r
c = 0
# Adding what the letter has found to a variable (will be replaced with a list).
r1 = r1 + v
b = b + 1
I will eventually make this a loop.
I added comments to the code so it's more understandable.
Essentially, you are trying to programmatically, dynamically modify the heap space where the variables live. I really do not think this is possible. If it is, it is very obscure.
I do understand where you are coming from. When I was first learning to program I had thought to solve problems in ways that would require such "dynamically created" variables. The solution really is to recognize what kind of (collection) data structure fits your needs.
If you want variables a1 through a30, create a list a. Then a1 would be a[1], a30 would be a[30]. It is a little different to write, but it should give you the behavior you need.
I spent at least five minutes trying to think why you would want to do this in the first place, until I decided I could actually write the code in less than five minutes, and hoping that in return you'd tell us why you want to do this.
Here's the code:
def new(value):
highest = -1
for name in globals():
if name.startswith('a'):
try:
number = int(name[1:])
except:
continue
if number > highest:
highest = number
globals()['a%d' % (highest + 1, )] = value
new("zero")
new("one")
new("two")
print a2 # prints two

Categories