While loops where only conditions are executed? [duplicate] - python

This question already has answers here:
Remove all occurrences of a value from a list?
(26 answers)
Closed 2 years ago.
So I want to execute only while loop statements, without putting anything inside them. For example, I have an array arr from which I have to remove multiple occurrences of some element. The instant the condition statement returns an error, while loop should end.
arr=[1,2,4,2,4,2,2]
This removes only one 2:
arr.remove(2)
I need to run this as long as it does not return error. (C++ has a semicolon put after while to do this).
I want something like this
while(arr.remove(2));

Three things.
First, it's not considered good practice in Python – it's not "pythonic" – to use an expression for its side effects. This is why, for example, the Python assignment operator is not itself an expression. (Although you can do something like a = b = 1 to set multiple variables to the same value, that statement doesn't break down as a = (b = 1); any such attempt to use an assignment statement as a value is a syntax error.)
Second, modifying data in place is also discouraged; it's usually better to make a copy and make the changes as the copy is constructed.
Third, even if this were a good way to do things, it wouldn't work in this case. When the remove method succeeds, it returns None, which is not truthy, so your loop exits immediately. On the other hand, when it fails, instead of returning a false value, it throws an exception, which will abort your whole program instead of just the loop, unless you wrap it in a try block.
So the list comprehension probably is the best solution here.

The way you are looking to solve this does not yield the results you are looking for. Since you are looking to create a new list, you are not going to want to use the remove function as per #Matthias comment. The idiomatic way to do it would be something along the lines of this:
arr=[1,2,4,2,4,2,2]
arr = [x if x != 2 for x in arr]

So I want to execute only while loop statements, without putting anything inside them.
That's really not necessary. Don't try to copy other language's syntax in Python. Different languages are designed with different objectives and hence, they have different syntax (or grammar of the language). Python has a different way of doing things than C++.
If you want to focus on the effectiveness of the program, then that's the different story. See this for more information on this.
Unfortunately, remove doesn't return anything (it returns None). So, you can't have anything that would look neat and clean without putting anything inside while.
Pythonic way to remove all occurrence of a element from list:
list(filter((2).__ne__, arr))
Or
arr = [x for x in arr if x != 2]
Or
while 2 in arr:
arr.remove(2)

you can use:
arr = [1,2,4,2,4,2,2]
try:
while arr.pop(arr.index(2)):
pass
except ValueError:
pass
print(arr)
#[1, 4, 4]

I am assuming you want to remove all occurrences of an element. This link might help you.
click here

Related

How to change List parenthesis from [] to none

short Question in Code:
i=0
k_start[i]
[8515]
i=1
k_start[i]
139253
How can i avoid the parenthesis in this example? Or Why at least do they appear with when i is 0?
Edit: Sorry for this bad Question, the problem was that i had a list of lists.
I'm not sure why your first element is coming out as a sub-list but you can get rid of the brackets (in this one specific case) by calling k_start[0][0]... Try printing k_start to see what the whole array looks like. That way you can see what is happening and perhaps find a more general solution. It's hard to do from the outside without more info, such as upstream code or a printout of the array.

Trouble with Palindrome function in python

I'm having trouble in an online course for python, specifically a palindrome problem These are the instructions, but the function must be case-insensitive and not see spaces. I think the issue is in my return blocks or my flow. I think I need to use the lower function, but I'm honestly not sure.
def student_func(x):
for string in x:
x.lower()
y = x.replace(" ", "")
if y[::-1]==y:
return True
else:
return False
You actually have two separate problems in your code—and you're right that one of them is with lower and the other is with the return flow.
First, x.lower() doesn't modify x in-place. In fact, strings are immutable; nothing modifies them in-place. If you look up the interactive help or the online docs, it says:
Return a copy of the string with all the cased characters [4] converted to lowercase.
So, you need to do the same thing with lower that you do with replace: assign the result to a variable, and use that:
y = x.lower()
z = y.replace(" ", "")
Or you can reuse the same variable:
x = x.lower()
… or chain the two calls together:
y = x.lower().replace(" ", "")
As a side note, unless you're using Python 2, you should consider whether you want casefold instead of lower. For English it makes no difference, but for other languages it can.
Meanwhile, you're doing for string in x:, but then ignoring string.
If x is just a single word, you don't want to loop over it at all.
If x is a list of words, then the for string in x: is correct, but then you have to use string inside the loop, not x. Plus, you can't just return True or return False—that will exit the function as soon as you test the first word, meaning the rest of them never get tested. I'm not sure whether you want to return True if there are any pallidromes, or if they're all palindromes, or if you want to return a list of booleans instead of a single one, or what, but you can't just return the first one.
It would probably be a lot clearer if you used better names, like words instead of x and word instead of string.
Anyway, I can't tell you the right way to fix this since I don't know what you're trying to do, but hopefully this explains enough that you can fix it yourself.
Giving away the solution defeats the purpose of the exercise
your approach is more or less correct.
convert string to a standard case
remove whitespace
check if reverse of the string is equal to the original string
The error lies in how you are using the python API.
check what each of the functions do, and what they return.
a good idea is to run help(function) to see what the function's documentation has to say about it.
try help(x.lower) (note: not help(x.lower())) and see what the return value is.

Why am I getting a syntax error for this conditional statement?

I've recently been practicing using map() in Python 3.5.2, and when I tried to run the module it said the comma separating the function and the iterable was a SyntaxError. Here's the code:
eng_swe = {"merry":"god", "christmas":"jul", "and":"och", "happy":"gott",
"new":"nytt", "year":"år"}
def map_translate(l):
"""Translates English words into Swedish using the dictionary above."""
return list(map(lambda x: eng_swe[x] if x in eng_swe.keys(), l))
I noticed that if I eliminate the conditional statement like this:
return list(map(lambda x: eng_swe[x], l))
it works fine, but it sacrifices the ability to avoid attempting to add items to the list that aren't in the dictionary. Interestingly enough, there also weren't any problems when I tried using a conditional statement with reduce(), as shown here:
from functools import reduce
def reduce_max_in_list(l):
"""Returns maximum integer in list using the 'reduce' function."""
return reduce(lambda x, y: x if x > y else y, l)
Yes, I know I could do the exact same thing more cleanly and easily with a list comprehension, but I consider it worth my time to at least learn how to use map() correctly, even if I end up never using it again.
You're getting the SyntaxError because you're using a conditional expression without supplying the else clause which is mandatory.
The grammar for conditional expressions (i.e if statements in an expression form) always includes an else clause:
conditional_expression ::= or_test ["if" or_test "else" expression]
^^
In your reduce example you do supply it and, as a result, no errors are being raised.
In your first example, you don't specify what should be returned if the condition isn't true. Since python can't yield nothing from an expression, that is a syntax error. e.g:
a if b # SyntaxError.
a if b else c # Ok.
You might argue that it could be useful to implicitly yield None in this case, but I doubt that a proposal of that sort would get any traction within the community... (I wouldn't vote for it ;-)
While the others' explanations of why your code is causing a SyntaxError are completely accurate, the goal of my answer is to aid you in your goal "to at least learn how to use map() correctly."
Your use of map in this context does not make much sense. As you noted in your answer it would be much cleaner if you used a list comprehension:
[eng_swe[x] for x in l if x in eng_swe]
As you can see, this looks awfully similar to your map expression, minus some of the convolution. Generally, this is a sign that you're using map incorrectly. map(lambda... is pretty much a code smell. (Note that I am saying this as an ardent supporter of the use of map in Python. I know many people think it should never be used, but I am not one of those people, as long as it is used properly.)
So, you might be wondering, what is an example of a good time to use map? Well, one use case I can think of off the top of my head is converting a list of strs to ints. For example, if I am reading a table of data stored in a file, I might do:
with open('my_file.txt', 'r') as f:
data = [map(int, line.split(' ')) for line in f]
Which would leave me with a 2d-array of ints, perfect for further manipulation or analysis. What makes this a better use of map than your code is that it uses a built-in function. I am not writing a lambda expressly to be used by map (as this is a sign that you should use a list comprehension).
Getting back to your code, however... if you want to write your code functionally, you should really be using filter, which is just as important to know as map.
map(lambda x: eng_swe[x], filter(lambda x: eng_swe.get(x), l))
Note that I was unable to get rid of the map(lambda... code smell in my version, but at least I broke it down into smaller parts. The filter finds the words that can be translated and the map performs the actual translation. (Still, in this case, a list comprehension is probably better.) I hope that this explanation helps you more than it confuses you in your quest to write Python code functionally.

pythonic way to combine a lot of startswith statements

What is the "pythonic" way to combine a lot of startswith statements?
Here are the details:
I receive various types of messages from a server, which sends them with different first letters in order for receiver to quickly identify and sort them. I wrote a code with a lot of
if message.startswith('A'):
do_A()
elif message.startswith('B'):
do_B()
- like statements. However, I feel there is more pythonic way to write the code without many statements, like maybe to make a list of all possible first letters and have one startswith statement.
Other variants with if message[0]=='A' are even better, since it appears to be faster per this, and speed matters to me.
Use a dictionary mapping first letter to a function:
message_map = {'A': do_A, 'B': do_B}
dispatch = message_map.get(message[:1])
if dispatch is not None:
dispatch()
Functions in Python are first-class objects, so you can store them in a dictionary like this.
Note that I used a slice to get the first character; it'll result in an empty string if message happens to be empty, rather than throw an IndexError exception.

Is there a way to execute two statements based on <condition> in one line?

Is it possible to write a one line like this: <statement> if <cond> else <statement>. I don't mean something like a = 1 if 1 else 2.
Example:
I have a list p that in itself has lists. Let's assume I get an input inputIter. I would like to do the following:
for input in inputIter:
if <condition>: p+=[[input]] # generate new list
else: p[-1]+=[input] # append to latest list
Then I thought to myself that there has to be a way to make this a one-liner so I tried this:
for input in inputIter:
p+=[[input]] if <condition> else p[-1]+=[input]
But this generates
Syntax error: invalid syntax ^
(where the = is at). Is there a workaround? I know this may not be the best example. I know it may look a bit ugly. But in my opinion it is readable.
You cannot mix statements into assignments, no.
Assignment is a statement (=, +=, etc.). An assignment statement contains an expression (everything to the right of the =), but it cannot itself be used inside of an expression. There are specific reason for this: assignments in expression lead to hard-to-find bugs. The classical example is confusing equality testing (==) with assignment:
if x = 0:
# oops, that wasn't a test..
See the Python FAQ.
You are trying to switch between assignments within a conditional expression, and that's not allowed in Python.
Just use if statements; in your specific example you could perhaps use:
for input in inputIter:
if <condition>:
p.append([]) # generate new list
p[-1].append(input)
This always appends to the last nested list, but when <condition> is a new, empty list is added at the end first.

Categories

Resources