Meaning of r[( s== 'even'::2) in python function - python

Question that asks:
"Create a function that returns the characters from a list or string r
on odd or even positions, depending on the specifier s. The specifier
will be "odd" for items on odd positions (1, 3, 5, ...) and "even" for
items on even positions (2, 4, 6, ...)."
E.g. char_at_pos([2, 4, 6, 8, 10], "even") ➞ [4, 8]
Have managed to solve, but saw a quicker way to solve would be to use:
def char_at_pos(r, s):
return r[s == 'even'::2]
am wondering how to interpret r[s == 'even'::2], is that adding a condition inside the index bracket before we pick the even index numbers in the list? How does it then also pick the odd numbers?

r[s == 'even'::2]
s == 'even' evaluates to 1 (which is the numerical equivalent for True) if s is 'even', otherwise it evaluates to zero (which is the numerical equivalent for False). Now lets break it down based on examples:
r[1:10] takes all items startig at 1 till item 10 (excluded).
r[1:] takes all items starting at 1 till the end.
r[1:10:2] takes every second item starting at 1 till item 10, and
r[1::2] correspondingly takes every second item starting at 1 till the end.

Adding to the #jim answer,
Booleans in Python are implemented as a subclass of integers.
>>> int(True)
1
>>> int(False)
0
>>> issubclass(type(True), int)
True
>>> issubclass(type(False), int)
True
When you call r[s == 'even'::2] python calls the __getitem__ method of the list object with the slice object slice(True, None, None) or slice(False, None, None)[Depends upon the result of s == 'even']. The PySlice_Unpack C API call will extract the start, stop, step data members from a slice object as C integers. So this is where the start(boolean object) argument is actually is converting to an int object making the expression to be evaluated as same as r[1::2] or r[0::2]

Related

How does and&or work in print() function? [duplicate]

This question already has answers here:
How do "and" and "or" act with non-boolean values?
(8 answers)
Closed 3 years ago.
Saw this while searching and I couldn't understand the logic behind. How does and & or methods work in print()?
T=[int(s) for s in input().split()]
print(T and sorted(sorted(T,reverse=True),key=abs)[0] or 0)
I've tried simplifying it to understand how it handles different inputs.
print(A and B or C)
Returns B when B is not 0, and returns C when B is 0 but never gets to A.
This is an old style way to use ternary condition operator.
It has nothing related to print.
See this answer.
In most cases it does the same as this code
print(T and sorted(sorted(T,reverse=True),key=abs)[0] or 0)
print(sorted(sorted(T,reverse=True),key=abs)[0] if T else 0)
It works because of the way and and or works in Python - they do not return bool, but they return either first or second operand, depending if it casts to True or False.
This answer has more details.
Basically it's two operation
first = T and sorted(sorted(T,reverse=True),key=abs)[0]
and Return the first Falsy value if there are any, else return the last value in the expression.
So it either returns [] (possible Falsy value for T), or first element in sorted list.
result = first or 0
or Return the first Truthy value if there are any, else return the last value in the expression.
So if T is Truthy, we already have a Truthy value in first (unless it's 0, which is special case, but 0 or 0 is 0 anyway), it will be returned.
If T is [] - it will return 0.
As part of the answer, if given a non-empty list, T, of integers, the expression
sorted(sorted(T,reverse=True),key=abs)[0]
returns the integer in the list which is closest to zero. For example, if T = [3, -2, 4, 5], it will return -2.
The subtle point is what is does in a case like T = [3, -2, 4, 2] where -2 and 2 are tied in being closest. In this case it will return 2 rather than -2. The logic for this particular case is that sorted(T, reverse = True) will put all of the positive numbers before any of the negative numbers, so that 2 will be before -2. When the result of that sort is then sorted again with key = abs, the 2 and -2 are already in sorted order (relative to key = abs), so they won't be swapped, hence 2 rather than -2 will be the first element of the list. The code is actually somewhat subtle and depends on the fact that Timsort is a stable sorting algorithm.

Why is my loop not following its condition?

so im working on this code for school and i dont know much about python. Can someone tell me why my loop keeps outputting invalid score when the input is part of the valid scores. So if i enter 1, it will say invalid score but it should be valid because i set the variable valid_scores= [0,1,2,3,4,5,6,7,8,9,10].
This code has to allow the user to enter 5 inputs for six different groups and then add to a list which will find the sum of the list and the avarage of the list.
Code:
valid_scores =[0,1,2,3,4,5,6,7,8,9,10]
for group in groups:
scores_for_group = []
valid_scores_loops=0
print("What do you score for group {group_name} as a player?"\
.format(group_name=group))
while valid_scores_loops < 5:
valid_scores=True
player_input =input("* ")
if player_input==valid_scores:
player1.append(player_input)
scores_for_player.append(int(player_input))
else:
if player_input!=valid_scores:
valid_scores= False
print("Invalid score!")
You're setting valid_scores=True, which overwrites your list of valid scores with a boolean value of True. Then, when you check player_input!=valid_scores, it will always return False.
What you want to do is get rid of the valid_scores=True line, cast the player_input to an integer using int(player_input), then check int(player_input) in valid_scores. This will return True if the player inputs a string that can be cast to one of the integers in valid_scores.
In your code there you are comparing a list (the valid values) with a string (the input.) This means you would have to give in a list for the statement to be correct. The right way is input in valid_inputs, which will check if any of the elements in the valid_inputs list equals the variable input. You're also assigning True to valid_inputs, which essentially deletes the list. Another error is that the player1 and scores_for_player variables aren't defined in your code. To fix your code, you'll have to cast the input to an integer, the variable storing if the input is valid must be renamed, the variables player1 and scores_for_player must be declared, and you probably should adjust your code with the fixes below.
You can also improve your code by replacing while valid_score_loops < 5 with for valid_score_loops in range(5) because you don't change valid_score_loops in loop. Another way for you to express [0,1,2,3,4,5,6,7,8,9,10] is to convert it to a tuple: (0,1,2,3,4,5,6,7,8,9,10) or express it as a range: range(0, 11).
Ranges are objects like lists and tuples that contain a sequence of numbers. The signatures of the range method are:
range(end) with start equivalent to 0 and step to 1
range(start, end) with step equivalent to 1
range(start, end, step)
It will start at start and increase by step each time, ending before end.
Example:
>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(range(3, 5))
[3, 4]
>>> list(range(1, 6, 2))
[1, 3, 5]
There is another optimization to make to your code. If the input isn't valid, it is invalid, so you don't have to check that in your code. To fix that, you can just remove the check if the argument isn't in the valid_scores list inside the else clause.

Count the number of times each element appears in a list. Then making a conditional statement from that

write a function that takes, as an argument, a list called aList. It returns a Boolean True if the list contains each of the integers between 1 and 6 exactly once, and False otherwise.
This is homework and I thought I had it right, but it is now telling me that it isn't right. Here is my code.
def isItAStraight(aList):
count = 0
for i in set(aList):
count += 1
return aList.count(i) == 1
for some reason even if a number appears more than once it still gives true and I can't figure out why it won't give me false unless the first or last number are changed.
Each number has to occur only one time otherwise it is false.
So like take [1,2,3,4,5,6]
would be true.
But [1,2,2,3,4,5]
would be false.
Also, I can't import things like Counter or collections (though it would be so much easier to do it isn't apart of the assignment.)
The list is randomly generated from 1 to 6.
With a return inside the loop, you are only checking one value. You need to check each value. Also, instead of looping through the items of the list, you should loop through the items you're actually looking for. It would also help to make sure there are the correct number of items in the list.
def isItAStraight(aList):
if len(aList) != 6:
return False
for i in range(1, 7):
if aList.count(i) != 1:
return False
return True
But the easiest way to do this is to simply sort the list and check if it's what you're looking for:
def isItAStraight(aList):
return sorted(aList) == list(range(1, 7))
You need to be careful about what's inside the list. What you've written is a basically the same as the pseudo-code below:
let count = 0
for every unique element in aList:
Add 1 to count
if count is now 1, return true.
This will always return true if there is at least one element in aList, since you're adding 1 to count and then returning immediately.
A couple approaches to consider:
Create a 6 element list of all zeros called flags. Iterate over aList and set the corresponding element in flags to 1. If flags is all ones, then you return true.
Sort the list, then check if the first six numbers are 1, 2, 3, 4, 5, 6.

How to check consecutive number in list?

This is my homework.
The problem is to find a way to check whether the items in a list are consecutive or not.
The following is code I've written:
def consecutive(var):
for x in range(2, len(var)):
forward = var[x] - var[x-1]
backward = var[x-1] - var[x-2]
if forward == backward:
return True
else:
return False
var = []
print 'Enter your number:'
while True:
num = raw_input()
if num == '':
break
var += [int(num)]
print consecutive(var)
If I input numbers like 1, 2, 3, 4, 5 then I will get True
If I input numbers like 2, 6, 3, 9, 7, 1, 4 then I'll get False
Here, I succeeded returning True or False values respectively.
But there're two questions that make me upset because if I use my code to solve the questions, I don't get the value that I want (it gives me an error)
First question: Is an empty list considered a consecutive list or not?
Second: Is a list that involves a single value considered a consecutive list or not?
Would you like to help me?
By mathematical convention as discussed in the comments, it would be standard to consider both an empty list and a list with a single element as consecutive, should it not be specified in your homework more precisely.
By the logic of vacuous truth, were a list to not have consecutive order it would require enough elements (2) to break this condition of ordering. To handle this in your existing code, you could simply perform a check before your main check to ensure the base cases of an empty list and a list with one element return True.

How do boolean operators work in 'if' conditions?

I am currently new to Python and am trying to run a few simple lines of code. I cannot understand how Python is evaluating this syntax after the if statement. Any explanations will be appreciated.
number = int(raw_input("Enter number : "))
if number == (1 or 2 or 3):
print "Match"
else:
print "No match"
Only the integer 1 yield a positive result and any other numbers including 2 and 3 go through the else branch. Can the conditions be stated as the following only?:
if number == 1 or number == 2 or number == 3:
Thank you.
You probably want:
if number in (1, 2, 3):
Python has boolean values, such as True and False, and it also has falsy values, such as any empty list, tuple, or dictionary, an empty string, 0, and None. Truthy values are the opposite of that, namely anything that's defined.
Python's or evaluates and short-circuts on the first element that returns a truthy value.
So, the expression (1 or 2 or 3) is going to return 1.
If you want to compare against all elements, then you're looking for the in keyword:
if number in (1, 2, 3):
# Do logic
The or operator takes two arguments, on its left and right sides, and performs the following logic:
Evaluate the stuff on the left-hand side.
If it is a truthy value (e.g, bool(x) is True, so it's not zero, an empty string, or None), return it and stop.
Otherwise, evaluate the stuff on the right-hand side and return that.
As such, 1 or 2 or 3 is simply 1, so your expression turns into:
if number == (1):
If you actually mean number == 1 or number == 2 or number == 3, or number in (1, 2, 3), you'll need to say that.
(Incidentally: The and operator works the same way, except step 2 returns if the left-hand-side is falsey.)

Categories