I have a piece of code that broke the other day and I can't find the problem. I need to do something if I find a coincidence between a user input and the first value of any element of a list of lists.
I had this code running in another computer, but somehow I can't make it run anymore:
if any(orderinput == x[0] for x in order):
orderinput is the user input and order is the list of lists. This worked once and should be working based on what I've read here on stackoverflow, but it throws a syntax error at the r in for.
I tried moving it between lines or adding spaces, but the error follows the r.
I'm working in Python 2.2. I don't remember the version in the machine I made the code.
Generator expressions are available since python 2.4. Try changing to a list comprehension:
if any([orderinput == x[0] for x in order]):
Python 2.2 is twelve years old. A lot of things were different.
Related
I have some code that I have been running in Python 3.6, but when I move to Python 3.9 I recieve the below error:
SyntaxError: can't use starred expression here
I understand some syntax related to expressions of the form (*something) was implemented in 3.9 that is not backwards compatible (see, for example, here).
Here is a minimal working example of what my code tries to do:
# Get some data
y = np.random.randn(100,100,100)
# Indexes stored as a tuple
x = (1,2)
# Result I'm after
result = y[...,(*x)]
In the above example, I am trying to essentially return y[:,1,2], but in practice, my tuple may have more values, and my array may be larger.
The above code works fine in Python 3.6 but doesn't work in Python 3.9. I cannot work out what the equivalent piece of code would be in Python 3.9 and above. I don't want to assume the number of dimensions in Y (e.g. I want to keep the ...), but I want to retain the behaviour I have above. How can I do this?
You were almost there:
result = y[(..., *x)]
Intermediate:
(..., *x)
# (Ellipsis, 1, 2)
I am a beginner in python and learning "Learn Python: The Complete Python Programming Course" using Udemy. I downloaded Python 3.8. All things were good until I reached placeholders:
for i in arr.
Print(sen%(āiā))
I just want to use the function of placeholders in python and complete the task by placing multiple names in an array. I cannot type any of this. May I know why?
I am stuck and can't move ahead in the learning of the course.
Try:
for i in arr:
print(sen%(i))
That is, replace arr. to arr:
It is a bit finicky and will throw an error if the statement isn't lined up correctly, if you hit return in the wrong spot, or put a space where there shouldn't be one.
As #Joshua Varghese suggested, first change arr. to arr:
Make sure there is no space in arr:print(sen%(i))
Put your curser just before print(sen%(i)), and hit return. (This will put your print statement on the next line with the correct spacing).
To have your program execute and iterate through the array of names, you need to have your curser on the next line, the line following print(sen%(i)), then hit return.
Note: using python 3.9.2 on Mac OS
I am a Python newbie using Jupyter Notebook, and I am coming across the following problem:
I create 2 very simple lists and assign them to their own respective variables, which works fine.
My code is below:
x = [-2,1,3]
y = [-1,1,2]
I then execute other pieces of simple code, which involves using Matplotlib to plot a graph with values from the lists and also multiplying each element in the lists.
However, I noticed when I try to print the original lists after initialising them, I only get the last element from the list as an integer, not in list form. I find this strange as I haven't made any changes to the lists.
The issue isn't prominent, because I'm still able to continue to use the lists in their original form e.g. to plot the graph, but I'm wondering why this is happening, hoping to strengthen my Python/programming knowledge...
I've added screenshots to display my issue more clearly, but please ask me to explain anything if I haven't made myself clear.
Thanks in advance everyone!!
I think there is an issue in your output of Jupyter, because you pass from the line 93 to 88 and between we don't see the instructions you used.
I might be wrong , but your problem is that you are giving the same name for both the iterator and the sequence in line 85. instead of doing this:
xy = [x*y for x,y in zip(x,y)]
try this:
xy = [i*j for i,j in zip(x,y)]
There's some weird mysterious behavior here.
EDIT This has gotten really long and tangled, and I've edited it like 10 times. The TL/DR is that in the course of processing some text, I've managed to write a function that:
works on individual strings of a list
throws a variety of errors when I try to apply it to the whole list with a list comprehension
throws similar errors when I try to apply it to the whole list with a loop
after throwing those errors, stops working on the individual strings until I re-run the function definition and feed it some sample data, then it starts working again, and finally
turns out to work when I apply it to the whole list with map().
There's an ipython notebook saved as html which displays the whole mess here: http://paul-gowder.com/wtf.html ---I've put a link at the top to jump past some irrelevant stuff. I've also made a[nother] gist that just has the problem code and some sample data, but since this problem seems to throw around a bunch of state somehow, I can't guarantee it'll be reproducible from it: https://gist.github.com/paultopia/402891d05dd8c05995d2
End TL/DR, begin mess
I'm doing some toy text-mining on that old enron dataset, and I have the following set of functions to clean up the emails preparatory to turning them into a document term matrix, after loading nltk stopwords and such. The following uses the email library in python 2.7
def parseEmail(document):
# strip unnecessary headers, header text, etc.
theMessage = email.message_from_string(document)
tofield = theMessage['to']
fromfield = theMessage['from']
subjectfield = theMessage['subject']
bodyfield = theMessage.get_payload()
wholeMsgList = [tofield, fromfield, subjectfield, bodyfield]
# get rid of any fields that don't exist in the email
cleanMsgList = [x for x in wholeMsgList if x is not None]
# now return a string with all that stuff run together
return ' '.join(cleanMsgList)
def lettersOnly(document):
return re.sub("[^a-zA-Z]", " ", document)
def wordBag(document):
return lettersOnly(parseEmail(document)).lower().split()
def cleanDoc(document):
dasbag = wordBag(document)
# get rid of "enron" for obvious reasons, also the .com
bagB = [word for word in dasbag if not word in ['enron','com']]
unstemmed =[word for word in bagB if not word in stopwords.words("english")]
return [stemmer.stem(word) for word in unstemmed]
print enronEmails[0][1]
print cleanDoc(enronEmails[0][1])
First (T-minus half an hour) running this on an email represented as a unicode string produced the expected result: print cleanDoc(enronEmails[0][1]) yielded a list of stemmed words. To be clear, the underlying data enronEmails is a list of [label, message] lists, where label is an integer 0 or 1, and message is a unicode string. (In python 2.7.)
Then at t-10, I added a couple lines of code (since deleted and lost, unfortunately...but see below), with some list comprehensions in them to just extract the messages from the enronEmails, run my cleanup function on them, and then join them back into strings for convenient conversion into document term matrix via sklearn. But the function started throwing errors. So I put my debugging hat on...
First I tried rerunning the original definition and test cell. But when I re-ran that cell, my email parsing function suddenly started throwing an error in the message_from_string method:
AttributeError: 'list' object has no attribute 'message_from_string'
So that was bizarre. This was exactly the same function, called on exactly the same data: cleanDoc(enronEmails[0][1]). The function was working, on the same data, and I haven't changed it.
So checked to make extra-sure I didn't mutate the data. enronEmails[0][1] was still a string. Not a list. I have no idea why traceback was of the opinion that I was passing a list to cleanDoc(). I wasn't.
But the plot thickens
So then I went to a make a gist to create a wholly reproducible example for the purpose of posting this SO question. I started with the working part. The gist: https://gist.github.com/paultopia/c8c3e066c39336e5f3c2.
To make sure it was working, first I stuck it in a normal .py file and ran it from command line. It worked.
Then I stuck it in a cell at the bottom of my ipython notebook with all the other stuff in it. That worked too.
Then I tried the parseEmail function on enronEmails[0][1]. That worked again. Then I went all the way back up to the original cell that was throwing an error not five minutes ago and re-ran it (including the import from sklearn, and including the original definition of all functions). And it freaking worked.
BUT THEN
I then went back in and tried again with the list comprehensions and such. And this time, I kept track more carefully of what was going on. Adding the following cells:
1.
def atLeastThreeString(cleandoc):
return ' '.join([w for w in cleandoc if len(w)>2])
print atLeastThreeString(cleanDoc(enronEmails[0][1]))
THIS works, and produces the expected output: a string with words over 2 letters. But then:
2.
justEmails = [email[1] for email in enronEmails]
bigEmailsList = [atLeastThreeString(cleanDoc(email)) for email in justEmails]
and all of a sudden it starts throwing a whole new error, same place in the traceback:
AttributeError: 'unicode' object has no attribute 'message_from_string'
which is extra funny, because I was passing it unicode strings a minute ago and it was doing just fine. And, just to thicken the plot, then going back and rerunning cleanDoc(enronEmails[0][1]) throws the same error
This is driving me insane. How is it possible that creating a new list, and then attempting to run function A on that list, not only throws an error on the new list, but ALSO causes function A to throw an error on data that it was previously working on? I know I'm not mutating the original list...
I've posted the entire notebook in html form here, if anyone wants to see full code and traceback: http://paul-gowder.com/wtf.html The relevant parts start about 2/3 of the way down, at the cells numbered 24-5, where it works, and then the cell numbered 26, where it blows up.
help??
Another edit: I've added some more debugging efforts to the bottom of the above-linked html notebook. As you can see, I've traced the problem down to the act of looping, whether done implicitly in list comprehension form or explicitly. My function works on an individual item in the list of just e-mails, but then fails on every single item when I try to loop over that list, except when I use map() to do it. ???? Has the world gone insane?
I believe the problem is these staements:
justEmails = [email[1] for email in enronEmails]
bigEmailsList = [atLeastThreeString(cleanDoc(email)) for email in justEmails]
In python 2, the dummy variable email leaks out into the namespace, and so you are overwriting the name of the email module, and you are then trying to call a method from that module on a python string. I don't have ntlk in python 2, so I cant test it, but I think this must be it.
How do I trim the output of Python Pyenchat Module's 'suggested words list ?
Quite often it gives me a huge list of 20 suggested words that looks awkward when displayed on the screen and also has a tendency to go out of the screen .
Like sentinel, I'm not sure if the problem you're having is specific to pyenchant or a python-familiarity issue. If I assume the latter, you could simply select the number of values you'd like as part of your program. In simple form, this could be as easy as:
suggestion_list = pyenchant_function(document_filled_with_typos)
number_of_suggestions = len(suggestion_list)
MAX_SUGGESTIONS = 3 # you choose what you like
if number_of_suggestions > MAX_SUGGESTIONS:
answer = suggestion_list[0:(MAX_Suggestions-1)] # python lists are indexed to 0
else:
answer = suggestion_list
Note: I'm choosing to be clear rather than concise here, since I'm guessing that will be valued by asker, if asker is unclear on using list indices.
Hope this helps and good luck with python.
Assuming it returns a standard Python list, you use standard Python slicing syntax. E.g. suggestedwords[:10] gets just the first 10.