New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
random.shuffle loses most of the elements #87784
Comments
This issue is probably related to issue ??? but I have created it as a separate issue. When shuffle doesn't crash it sometimes (or maybe always - I haven't fully analysed this yet) looses most of the elements in the list that it is supposed to be shuffling. Here is an extract of the code that I'm using: import io
from io import StringIO
from lxml import etree
import random
filename_xml = 'MockExam5.xml'
with io.open(filename_xml, mode="r", encoding="utf-8") as xml_file:
xml_to_check = xml_file.read()
doc = etree.parse(StringIO(xml_to_check))
exams = doc.getroot()
questions_element = exams.find("questions")
logmsg(L_TRACE, "There are now " + str(len(questions_element.findall("question"))) + " questions")
logmsg(L_TRACE, "Randomising order of questions in this exam")
random.shuffle(questions_element)
logmsg(L_TRACE, "Finished randomise")
logmsg(L_TRACE, "There are now " + str(len(questions_element.findall("question"))) + " questions") And here is the log produced by this code: 21-03-24 18:10:11.989 line: 2057 file: D:\XPS_8700 Extended Files\Users\RowanB\Documents\My_Scripts NEW\mockexam\put_exam.py 2 There are now 79 questions How come the shuffle starts off with 79 elements, and finishes with 6? Thanks - Rowan |
Same advice as bpo-43616: please provide an example we can run. This most likely a problem with how you're using lxml, and not a bug in python. But since we can't test it, we can't know for sure. |
Are you sure it's "a list"? At least print out ... That's about all there is to it. Note that, for this purpose, it doesn't matter want |
The standard library isn't at fault here. Please file this an an LXML bug. Reproducer: from lxml.etree import Element
root = Element('outer')
root.append(Element('zero'))
root.append(Element('one'))
root.append(Element('two'))
print([e.tag for e in root])
root[1], root[0] = root[0], root[1]
print([e.tag for e in root]) This outputs: ['zero', 'one', 'two'] Replacing the import with: from xml.etree.ElementTree import Element Gives the expected result: ['zero', 'one', 'two'] |
Interestingly, this isn't an LXML bug. It is a documented difference from how the standard library works:
So, if you want use random.shuffle(), you need the standard library ElementTree instead of lxml. This: from lxml.etree import Element
root = Element('outer')
root.append(Element('zero'))
root.append(Element('one'))
root.append(Element('two'))
root[0] = root[1]
print([e.tag for e in root]) Produces: ['one', 'two'] |
Yes, this is neither a bug in CPython (or its stdlib) nor in lxml. It's how things work. Don't use these two together. |
As an immediate fix to your problem, replace this line: random.shuffle(questions_element) with: questions = list(questions_element)
random.shuffle(questions)
questions_element[:] = questions |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: