Re: [Tutor] Strange issue w/ Python shell 3.0.0.
On 24/11/13 07:51, Rafael Knuth wrote: So, what to do about it? While the Python interactive interpreter is mighty powerful, it does have some limitations, and this is one of them. You just have to get used to the fact that it is not well-suited for editing large blocks of code. ... Understood. Should I use a Python IDE like Pycharm or so? Would that help? If so, which ones would you recommend? IDLE is fine (assuming Steven is right and you are using IDLE) but get used to opening an edit window and creating the script there and then running that rather than typing everything into the Python Shell window. You can still use the shell to try out small snippets of code but anything bigger goes in a separate file. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Fibonacci Series
Hej there, I am making a couple wrong assumptions about the program below, but I do not know where my thinking mistake is. I have some trouble understanding what exactly happens within this loop here: a, b = 0, 1 while b < 10: print(b) a, b = b, a +b What I would expect as an outcome of that while loop, is: >> 1 2 4 8 Here's my (wrong) assumption about that while loop: 1st loop: Pretty much straight forward, as b = 1 on the first line of code. >> 1 2nd loop (the output of the 1st loop is "reused" inside the 2nd loop which is: b = 1): a = b = 1 b = a + b = 1 + 1 = 2 >> 2 3rd loop: a = b = 2 b = a + b = 2 + 2 = 4 >> 4 3rd loop: a = b = 4 b = a + b = 4 + 4 = 8 break. Instead, that program's correct output is: >> 1 1 2 3 5 8 I understand what a Fibonacci Series is, but I struggle to understand what's happening inside that while loop above. Also, I would assume that an arbitrary integer can be assigned to "a" on the first line as what really matters (in my understanding) is the new value assigned to "a" within the loop. This assumption is wrong as well: a, b = 999, 1 while b < 10: print(b) a, b = b, a +b >>> 1 The while loop breaks after b = 1 is printed out. ... which makes me wonder, because I would expect a = 999 to be changed to a = b = 1 after the first loop and the program should execute the 2nd loop in my understanding ... Can anyone clarify please? Thank you! All the best, Raf ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Fibonacci Series
Hi, > a, b = b, a +b > a = b = 1 > b = a + b = 1 + 1 = 2 Your issue is that you interpret the assignment wrong. You seem to think that it assigns b to a and THEN a+b to b, which is not the case. The right side of the assignment creates a tuple, and the left side unpacks it. It is the same as: t = (b, a+b) a = t[0] b = t[1] You see that a has not been assigned yet when the second part is calculated. Cheers, Nik -- * mirabilos is handling my post-1990 smartphone * Aaah, it vibrates! Wherefore art thou, demonic device?? PGP-Fingerprint: 3C9D 54A4 7575 C026 FB17 FD26 B79A 3C16 A0C4 F296 signature.asc Description: Digital signature ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Fibonacci Series
On Sun, 24 Nov 2013 11:24:43 +0100, Rafael Knuth wrote: a, b = b, a +b a = b = 1 b = a + b = 1 + 1 = 2 I suggest you play with the statement a bit. Print out both values each time through the loop. The expression b, a+b produces a tuple. The left side a, b *unpacks* that tuple into the two variables.a and b. Perhaps a simpler case might help. Try a, b = b, a What would you expect it to do and why? -- DaveA ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Fibonacci Series
Now I got it, thanks :-) a, b = b, b + a ... I was was wrongly assuming that "a" and "b" on the left side "talk" to each other and that "a" tells "b" something like: "Hey 'b' ... I just assigned another value to you, make sure you execute it." But "a" and "b" don't talk to each other. Each of them executes what it is supposed to and doesn't take notice of what its neighbor variable does. The more sophisticated explanation (from my view point as an absolute beginner who's not familiar with most programming concepts yet) is that "a" and "b" on the left side are unchangable tuples and they simply get unpacked on the right side. I wrote an even more primitive program which helped me understand what *exactly* happens with "a" and "b" with each run: # 1st run a, b = 1, 5 print(a) # 1 print(b) # 5 # 2nd run a, b = b, b + a print(a) # a = b = 5 print(b) # b + a = 5 + 1 = 6 # 3rd run a, b = b, b + a print(a) # a = b = 6 print(b) # b + a = 6 + 5 = 11 # 4th run a, b = b, b + a print(a) # a = b = 11 print(b) # b + a = 11 + 6 = 17 # 5th run a, b = b, b + a print(a) # a = b = 17 print(b) # b + a = 17 + 11 = 28 # 6th run a, b = b, b + a print(a) # a = b = 28 print(b) # b + a = 28 + 17 0 45 All the best, Raf On Sun, Nov 24, 2013 at 12:33 PM, Dave Angel wrote: > On Sun, 24 Nov 2013 11:24:43 +0100, Rafael Knuth > wrote: > >> a, b = b, a +b >> > > > a = b = 1 >> b = a + b = 1 + 1 = 2 >> > > I suggest you play with the statement a bit. Print out both values each > time through the loop. > > The expression b, a+b produces a tuple. The left side a, b *unpacks* that > tuple into the two variables.a and b. > > Perhaps a simpler case might help. Try a, b = b, a What would you expect > it to do and why? > > -- > DaveA > > ___ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Strange issue w/ Python shell 3.0.0.
On Sun, Nov 24, 2013 at 08:51:41AM +0100, Rafael Knuth wrote: > > So, what to do about it? While the Python interactive interpreter is > > mighty powerful, it does have some limitations, and this is one of them. > > You just have to get used to the fact that it is not well-suited for > > editing large blocks of code. It is excellent for trying out small > > snippets, or for running blocks of code that don't have to change, but > > not for editing and running at the same time (at least not until you're > > experienced enough to deal with errors like this one). > > Understood. Should I use a Python IDE like Pycharm or so? Would that help? > If so, which ones would you recommend? I have never found an IDE I really like. Actually, that's not quite true. Back in the late 1980s and early 1990s I had two IDEs I loved, although they weren't called IDEs back then because the TLA hadn't been invented. One was Apple's Hypercard, which was not just an IDE but a runtime GUI environment as well, and the other was Think's Pascal compiler. These days, my IDE of choice is called Linux. I have a web browser open for looking up code and help files on the internet, and a text editor open with at least two files (the program I'm working on, and a second program to test it). I prefer KDE 3's "kate" editor, like nearly everything about KDE version 4 is worse, but at a pinch Gnome's gedit will do. I also run a terminal that supports multiple tabs. I have at least three tabs open in the terminal: - one for running Linux commands and managing source control; - one for testing or running my program, which I normally do with a couple of commands: python myfile.py python myfile_tests.py - one open to a Python interactive interpreter, for testing code snippets. So that's three windows, and at least half a dozen tabs between them. I say at least, because the number of tabs in the terminal tends to rise and fall, or in the case of the browser, rise and rise and rise and rise. (Currently I have 110 browser tabs split over two browsers and four windows. Curse you Internet, why do you have so much interesting stuff?!) More here: http://blog.sanctum.geek.nz/series/unix-as-ide/ http://michaelochurch.wordpress.com/2013/01/09/ide-culture-vs-unix-philosophy/ And now I have 112 browser tabs open... -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Fibonacci Series
On 24/11/13 13:05, Rafael Knuth wrote: "a" and "b" on the left side are unchangable tuples and they simply get unpacked on the right side. Be careful about terminology here. a,b is a single tuple with two values. But a and b are variables not tuples. Tuples are collections of (one or more) values. In python they are separated by commas. Thus a single valued tuple looks like (5,) A double valued tuple like (3,4) And so on. Note the parentheses are optional and only needed for disambiguating the tuple. 3,4 is also a double valued tuple. Variables are names that refer to values. A value can be any Python object (including a tuple!). So a = None a = 5 a = 's' a = (1,2) are all valid values for the variable 'a' And t = ( (1,2), (2,3) ) is a single tuple composed of two other tuples. So a,b = 3,4 is assigning the tuple on the right side to the tuple on the left. It *simultaneously* assigns 3 to a and 4 to b. It doesn't matter what a and b were storing previously it creates a new tuple on the right and assigns it to another newly created one on the left. Note that the right side could be an existing tuple but the one on the left is always a new tuple. Thus a,b = t # see above would only create one new tuple (on the left) and a would have the value t[0], or (1,2) and b would be t[1] or (2,3). The final thing that makes your case complicated is that a,b appear on both sides of the assignment. But if you remember that the assignments are effectively happening simultaneously it all follows the same rules. Tuple assignment/unpacking is a powerful technique in Python. Without it we would need to introduce extra variables so that a,b = b, a+b would become old_a = a a = b b = old_a + b HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] minor display issue with python dictionaries
Hi, ## >>> >>> new_dict = {'a':10, 'b' :20, 'c': 30,'d' : 40} >>> >>> >>> print new_dict {'a': 10, 'c': 30, 'b': 20, 'd': 40} >>> # >From the above output, I see key 'c' is at third position during input, but while displaying the output it is displayed at second position Although, I dont see any impact of it since we mainly refer to dictionary values only using "keys" -- but just for curiosity why is this position change? Regards, Reuben ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Depth First Search Listing all possible combinations
So I cleaned up the code to make it readable. I'm not getting an error message now. What I'm getting is an empty bracket. I want to run find_all_paths with my graph and then list the start and end point (in this case that's q9 and q42) and then have it list a tuple of each path in a separate line. Each path being a unique way to get to the end point. Here's what I enter and I get back [] >>> find_all_paths(graph, 'q9', 'q42') [] What I want is >>> find_all_paths(graph, 'q9', 'q42') [q9, q10, q11 ,q15, q16, q17, q18, q20, q23, q34, q35, q36, q37, q38, q39, q41, q42, end] [then list another path.] [list another path] graph = {'q9': ['q10', 'q33'], 'q10': ['q11', 'q 28', 'q29', 'q30'], 'q11': ['q15'] , 'q16': ['q17', 'q19', 'q24'],' q18': ['q20'], 'q23': ['q34'], 'q24': ['q25', 'q26'], 'q27': ['q34'], 'q28': ['q30', 'q29'], 'q30': ['q34', 'q31', 'q12'], 'q32': ['q34'], 'q33': ['q15' , 'q30'], 'q35': ['q36', 'q37'], 'q37': ['q38', 'q39'], 'q39': ['q41', 'q40', 'q42'],'q42': ['end']} def find_path(graph, start, end, path=[]): path = path + [start] if start == end: return path if not graph.has_key(start): return None for node in graph[start]: if node not in path: newpath = find_path(graph, node, end, path) if newpath: return newpath return None def find_all_paths(graph, start, end, path=[]): path = path + [start] if start == end: return [path] if not graph.has_key(start): return [] paths = [] for node in graph[start]: if node not in path: newpaths = find_all_paths(graph, node, end, path) for newpath in newpaths: paths.append(newpath) return paths On Sat, Nov 23, 2013 at 7:13 PM, Alan Gauld wrote: > On 23/11/13 21:30, Randolph Scott-McLaughlin II wrote: > >> Inline image 2Inline image 1Hi Tutors, >> >> >> So I'm writing code for a depth first search where I have 1 start point >> and 1 end point. Between those points there are a series of 1-way roads >> that goes from one vertex to the next. Sometimes the vertex can have 4 >> or 5 one way road paths going into it or out of it. >> >> What I want to do is list each unique possible path someone can go from >> the start to end point, have the list written out and ideally labeled as >> "list'n'". >> >> Here's some code that I started off with but I keep getting errors >> > > What kind of errors? > And if there are error messages please provide copies of the entire error > message not just a summary. They are usually extremely > informative. > > > in general can't get it to do what I want it to do. >> > > What do you expect? What do you get? > Don't force us to try to run it, guess what it should do, > then assess what it is doing. > Tell us. > > > If you could guide me in the right direction or tell me how I can >> > > alter the code I've been coming across to fit my needs that'd > > be great. > > We can try but you need to tell us more detail too. > > > I've also attached an image of the road map that I'm trying to develop, >> along with the decisional points that each vertex can take someone to >> and from. Thanks for help! >> > > It may be helpful to somebody but not to me! :-( > > > #start=q9 >> q9 = (10, 33) >> q10 = (11, 28, 29, 30) >> q11 = (15) >> q16 = (17,19,24) >> q18 = (17, 19, 24) >> q24 = (25, 26) >> q27 = (34) >> q28 = (29, 30) >> q30 = (12, 31, 34) >> q32 = (34) >> q33 = (15, 30) >> q35 = (36, 37) >> q37 = (38, 39) >> q39 = (40, 41, 99) >> #end = 99 >> > > Could you do a smaller example that exhibits the problem? > > > #trying new DFS code >> parent = {s:None} >> def DFS_VISIT(V, Adj,s): >> for v in Adj[s]: >> s.inprocess=True >> if v not in parent: >> s.inprocess=False >> parent[v]=s >> DFS_VISIT(V,Adj,s) >> > > You are using recursion but its not clear how you stop > the recursion. Possibly when all elements of Adj[s] are > not parents? But it looks lie you never use V and > don't change Adj either. So I'm not sur4e how often > this will recurse, but it may be more than the fixed > limit compiled into Python. Is that one of the errors > you get? > > > #dfs visit code, controls checking notes around you >> def dfs(V,Adj): >> parent = {} >> for s in V: >> if s not in parent: >> parent[s] = None >> DFS_VISIT(V,Adj,s) >> > > Note that you define a new 'parent' here. This is local to this function > and hides the parent defined above DFS. But DFS will > continue to use the one defined at the top. Is that what you expected? > Its usually better to create unique names to avoid confusion. > > I have no idea what the stuff below does, it's way too much > for me to try to wade through. I can't see any sign of you > calling dfs() or DFS_VISIT() so I don't know what the > connection is. I gave up at that point. Sorry.
Re: [Tutor] minor display issue with python dictionaries
On Sun, Nov 24, 2013 at 11:03 AM, Reuben wrote: > Hi, > > ## new_dict = {'a':10, 'b' :20, 'c': 30,'d' : 40} print new_dict > {'a': 10, 'c': 30, 'b': 20, 'd': 40} > > > # > > > From the above output, I see key 'c' is at third position during input, but > while displaying the output it is displayed at second position > > Although, I dont see any impact of it since we mainly refer to dictionary > values only using "keys" -- but just for curiosity why is this position > change? > > Regards, > Reuben > > ___ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > The key is the way to the value. Depending on the implementation, python might find the value by different algorithms. Sometimes people call dictionaries 'hashes', which I believe refers to a method of indexing that does some algorithm on the key to get the value location. This is for speed and for space savings in memory. So, sometimes you might see a dictionary displayed in the order you entered it, but sometimes not. -- Joel Goldstick http://joelgoldstick.com ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Else vs. Continue
Hej there, I stumbled upon the "continue" statement and to me it looks like it does exactly the same as else. I tested both else and continue in a little program and I don't see any differences between both. Is my assumption correct or wrong? If the latter is the case: Can you give me examples of continue usage that couldn't be done with else? Here's my code sample I mentioned above: for num in range(2,10): if num % 2 == 0: print("Found an even number", num) continue print("Found a number", num) Same program with else: for num in range(2,10): if num % 2 == 0: print("Found an even number", num) else: print("Found a number", num) Thanks in advance! All the best, Raf ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] minor display issue with python dictionaries
On Mon, Nov 25, 2013 at 2:55 AM, Joel Goldstick wrote: > On Sun, Nov 24, 2013 at 11:03 AM, Reuben wrote: >> Hi, >> >> ## > > new_dict = {'a':10, 'b' :20, 'c': 30,'d' : 40} > > > print new_dict >> {'a': 10, 'c': 30, 'b': 20, 'd': 40} > >> >> >> # >> >> >> From the above output, I see key 'c' is at third position during input, but >> while displaying the output it is displayed at second position >> >> Although, I dont see any impact of it since we mainly refer to dictionary >> values only using "keys" -- but just for curiosity why is this position >> change? >> >> Regards, >> Reuben >> >> ___ >> Tutor maillist - Tutor@python.org >> To unsubscribe or change subscription options: >> https://mail.python.org/mailman/listinfo/tutor >> > The key is the way to the value. Depending on the implementation, > python might find the value by different algorithms. Sometimes people > call dictionaries 'hashes', which I believe refers to a method of > indexing that does some algorithm on the key to get the value > location. This is for speed and for space savings in memory. > > So, sometimes you might see a dictionary displayed in the order you > entered it, but sometimes not. And if order is important, you should look at using OrderedDict [1]. See here [2] for examples. [1] http://docs.python.org/2/library/collections.html#collections.OrderedDict [2] http://docs.python.org/2/library/collections.html#ordereddict-examples-and-recipes Best, Amit. -- http://echorand.me ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Else vs. Continue
Hi, > I stumbled upon the "continue" statement and to me it looks like it > does exactly the same as else. I tested both else and continue in a > little program and I don't see any differences between both. Is my > assumption correct or wrong? If the latter is the case: Can you give > me examples of continue usage that couldn't be done with else? In general, you can translate quite many code samples into different ones. The difference is that else is used in an if control block, and continue is used only in loops and does exactly one thing: Skip the rest of the loop body, and begin the next iteration. Of course, you could do a lot of tests in the loop and use a lot of else: pass blocks that, after hitting a point where you want to escape the loop, skip the rest of the effective code, but that's cumbersome. If you want to exit a loop at a certain point, just use continue (or break to skip all remaining operations). To add to your confusion: while loops do have an else part in Python: while CONDITION: ... do something ... else: ... do something else ... The else part is executed exactly in the case that CONDITION is no longer True - but *not* when you break from the loop before that. -nik -- * concerning Mozilla code leaking assertion failures to tty without D-BUS * That means, D-BUS is a tool that makes software look better than it actually is. PGP-Fingerprint: 3C9D 54A4 7575 C026 FB17 FD26 B79A 3C16 A0C4 F296 signature.asc Description: Digital signature ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Else vs. Continue
On Sun, Nov 24, 2013 at 4:41 PM, Dominik George wrote: > Hi, > >> I stumbled upon the "continue" statement and to me it looks like it >> does exactly the same as else. I tested both else and continue in a >> little program and I don't see any differences between both. Is my >> assumption correct or wrong? If the latter is the case: Can you give >> me examples of continue usage that couldn't be done with else? I applaud your industrious exploration lately. Don't forget the Python website. I googled 'python continue' and got this: http://docs.python.org/2/tutorial/controlflow.html#break-and-continue-statements-and-else-clauses-on-loops Google is your friend! https://mail.python.org/mailman/listinfo/tutor > -- Joel Goldstick http://joelgoldstick.com ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Else vs. Continue
On 24/11/13 21:32, Rafael Knuth wrote: I stumbled upon the "continue" statement and to me it looks like it does exactly the same as else. I tested both else and continue in a little program and I don't see any differences between both. for num in range(2,10): if num % 2 == 0: print("Found an even number", num) continue print("Found a number", num) Same program with else: for num in range(2,10): if num % 2 == 0: print("Found an even number", num) else: print("Found a number", num) It's certainly possible to use an if/else to mimic the behaviour of a continue, and in languages without continue that's exactly what you'd do. But consider this example which puts the continue inside the else clause: for num in range(7): if num%2 == 0: print 'its even' else: print 'its odd' continue evens.append(num) It's easy enough to do that without using continue but its not as simple as saying its the same as the else clause. The other difference is the amount of processing done. Let's assume we have a complex function that takes a long time to execute that we need to use in a secondary if test. Using continue can avoid that overhead. Lets say we have one that checks if a number is prime because we only want to collect prime numbers: primes = [] for n in range(1000) if n%2 == 0: even numbers aren't prime continue else: if isPrime(n): primes.append(n) Now the continue means the isPrime test never gets executed, saving a lot of processing. Without continue you would need to execute the test and the only way to save the time would be to move the n%2 test inside the isPrime() function - which you may not always be able to do easily - or wrap the isPrime like so: def myPrime(n): if n%2 == 0: return False else: return isPrime(n) and make the loop do this: primes = [] for n in range(1000): if myPrime(n): primes.append(n) But that still incurs a little bit extra cost in calling myPrime(). So in general, yes, you can always replace continue with an if/else but it often results in less efficient code, or code that's less readable (more indentation levels etc). HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Else vs. Continue
On 24/11/13 22:38, Alan Gauld wrote: Responding to my own post, never a good sign :-( primes = [] for n in range(1000) if n%2 == 0: even numbers aren't prime continue else: if isPrime(n): primes.append(n) Now the continue means the isPrime test never gets executed, saving a lot of processing. Without continue you would need to execute the test and the only way to save the time would be to move the n%2 test inside the isPrime() function As soon as I posted it I realized that wasn't true, you could do this instead... for n in range(1000): if n%2 == 1: if isPrime(n): primes.append(n) So a bad example, sorry. DeMorgan wins again. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Else vs. Continue
On 24/11/2013 21:41, Dominik George wrote: Hi, I stumbled upon the "continue" statement and to me it looks like it does exactly the same as else. I tested both else and continue in a little program and I don't see any differences between both. Is my assumption correct or wrong? If the latter is the case: Can you give me examples of continue usage that couldn't be done with else? In general, you can translate quite many code samples into different ones. The difference is that else is used in an if control block, and continue is used only in loops and does exactly one thing: Skip the rest of the loop body, and begin the next iteration. Of course, you could do a lot of tests in the loop and use a lot of else: pass blocks that, after hitting a point where you want to escape the loop, skip the rest of the effective code, but that's cumbersome. If you want to exit a loop at a certain point, just use continue (or break to skip all remaining operations). To add to your confusion: while loops do have an else part in Python: while CONDITION: ... do something ... else: ... do something else ... The else part is executed exactly in the case that CONDITION is no longer True - but *not* when you break from the loop before that. -nik To add to your confusion: for loops can also have an else part in Python: http://docs.python.org/3/tutorial/controlflow.html#break-and-continue-statements-and-else-clauses-on-loops -- Python is the second best programming language in the world. But the best has yet to be invented. Christian Tismer Mark Lawrence ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] minor display issue with python dictionaries
On Sun, Nov 24, 2013 at 09:33:11PM +0530, Reuben wrote: [...] > From the above output, I see key 'c' is at third position during input, but > while displaying the output it is displayed at second position Dictionaries are deliberately made unordered. That means the order that items will be displayed is free to vary, not only from how you entered them, but in principle they might even vary each time you inspect the dict. (They probably won't, but they could.) Python dicts are actually "hash tables", which is a standard computer science data structure that you can look up, but in a nutshell, a hash table is an array indexed by the key's hash value. Why do we care about hash tables? Because they make a really fast and efficient way to look up keys, and from the key get access to a value. Let's start with the simplest way to store a key and value pair, an unsorted table of pairs with a marker indicating "blank", so you know when you've reached the end. Here's an example of a half-filled table: { ("Hello", value), # key first, then some value ("World", value), ("Spam", value), ("Eggs", value), ("Cheese", value), , , , , , } In order to find a key in the table, you have to inspect every position until you reach either the key you are looking for, or , in which case you know that the key is not there. So to find "Eggs", you have to inspect "Hello", "World", "Spam" and finally "Eggs". On average, a successful search takes half as many inspections as there are keys, e.g. if you have 10 keys in the table, you need to inspect 5 positions; if there are 100 keys, you need to inspect 50 positions on average. If there are 1000 keys, you need to inspect 500 positions. This is pretty slow. Imagine looking up a word in a dictionary (a real paper dictionary), but with a twist: the words are in whatever order the dictionary writer first thought of them, not alphabetical order, so for any word you have to start at the beginning and read every single world until you find it. Obviously we can do better, by keeping the words sorted. Our table will look like this: { ("Cheese", value), ("Eggs", value), ("Hello", value), ("Spam", value), ("World", value), , , , , , } In this case, we can use a technique called "binary search" to narrow down the possible places the key might be. This is very much like what you probably do when looking up words in a paper dictionary: flip the dictionary open to the middle, then decide whether you've gone too far or not far enough. Each time, you split the remaining half in half again, until you've narrowed down to the page containing the word you want. In a sorted table with binary search, the savings over an unsorted table can be very high. With 10 keys, on average you will end up inspecting 3 or 4 items, which isn't much improvement over 5 for the unsorted case, but with 100 keys, you will inspect 6 or 7, and with 1000 keys, 9 or 10. With a million keys, you only need to inspect about 20 items to either find the key you are looking for, or determine it isn't there. Can we do better than binary search? Yes we can, and we do so with a hash table, which is what Python dicts are. The secret to the hash table is that instead of putting all the keys at the beginning of the table, we want the entries to be scattered at random all over the place. Only not quite at random, since we need a way to jump straight to the key when asked. That's the *hash function*, which converts a key to an arbitrary, and distinct, index: { , ("World", value), # hash of "World" is 1 ("Cheese", value), # hash of "Cheese" is 2 , , ("Eggs", value),# hash of "Eggs" is 5 , ("Spam", value),# hash of "Spam" is 7 , ("Hello", value), # hash of "Hello" is 9 } So the positions of the keys in the table depend on the keys, not the order you write them down. The advantage of this is that looking for a key requires (near enough to) constant time. If you want to see whether "Eggs" is in the table, it doesn't matter whether there are ten keys or ten billion, it will take exactly the same amount of time: hash the key "Eggs" to give you index 5, look at index 5, it is either there or it isn't. Now, in reality we can't actually guarantee that every hash value is distinct. In real life, a hash table has to deal with "collisions", which is when two different keys have the same hash value, and that will spoil the nice simple constant time performance. But collisions are usually rare, and so when discussing hash tables in broad terms we normally ignore them. In Python, you can calculate the hash value of a key with the hash() function. The exact values you get may depend on the specific version of Python you are using, but to give you an example: py> hash("cat") 405875055 py> hash("hat") 1255409212 py> hash("fat") -750391218 So you can see, by changing just one letter of the key, we get a completely differen
Re: [Tutor] minor display issue with python dictionaries
On Sun, Nov 24, 2013 at 8:12 PM, Steven D'Aprano wrote: > On Sun, Nov 24, 2013 at 09:33:11PM +0530, Reuben wrote: > [...] >> From the above output, I see key 'c' is at third position during input, but >> while displaying the output it is displayed at second position > > Dictionaries are deliberately made unordered. That means the order that > items will be displayed is free to vary, not only from how you entered > them, but in principle they might even vary each time you inspect the > dict. (They probably won't, but they could.) > > Python dicts are actually "hash tables", which is a standard computer > science data structure that you can look up, but in a nutshell, a hash > table is an array indexed by the key's hash value. Why do we care about > hash tables? Because they make a really fast and efficient way to look > up keys, and from the key get access to a value. > > Let's start with the simplest way to store a key and value pair, an > unsorted table of pairs with a marker indicating "blank", so you know > when you've reached the end. Here's an example of a half-filled table: > > { ("Hello", value), # key first, then some value > ("World", value), > ("Spam", value), > ("Eggs", value), > ("Cheese", value), > , > , > , > , > , > } > > In order to find a key in the table, you have to inspect every position > until you reach either the key you are looking for, or , in which > case you know that the key is not there. So to find "Eggs", you have to > inspect "Hello", "World", "Spam" and finally "Eggs". On average, a > successful search takes half as many inspections as there are keys, e.g. > if you have 10 keys in the table, you need to inspect 5 positions; if > there are 100 keys, you need to inspect 50 positions on average. If > there are 1000 keys, you need to inspect 500 positions. > > This is pretty slow. Imagine looking up a word in a dictionary (a real > paper dictionary), but with a twist: the words are in whatever order the > dictionary writer first thought of them, not alphabetical order, so for > any word you have to start at the beginning and read every single world > until you find it. > > Obviously we can do better, by keeping the words sorted. Our table will > look like this: > > { ("Cheese", value), > ("Eggs", value), > ("Hello", value), > ("Spam", value), > ("World", value), > , > , > , > , > , > } > > In this case, we can use a technique called "binary search" to narrow > down the possible places the key might be. This is very much like what > you probably do when looking up words in a paper dictionary: flip the > dictionary open to the middle, then decide whether you've gone too far > or not far enough. Each time, you split the remaining half in half > again, until you've narrowed down to the page containing the word you > want. > > In a sorted table with binary search, the savings over an unsorted table > can be very high. With 10 keys, on average you will end up inspecting 3 > or 4 items, which isn't much improvement over 5 for the unsorted case, > but with 100 keys, you will inspect 6 or 7, and with 1000 keys, 9 or 10. > With a million keys, you only need to inspect about 20 items to either > find the key you are looking for, or determine it isn't there. > > Can we do better than binary search? Yes we can, and we do so with a > hash table, which is what Python dicts are. > > The secret to the hash table is that instead of putting all the keys at > the beginning of the table, we want the entries to be scattered at > random all over the place. Only not quite at random, since we need a way > to jump straight to the key when asked. That's the *hash function*, > which converts a key to an arbitrary, and distinct, index: > > { , > ("World", value), # hash of "World" is 1 > ("Cheese", value), # hash of "Cheese" is 2 > , > , > ("Eggs", value),# hash of "Eggs" is 5 > , > ("Spam", value),# hash of "Spam" is 7 > , > ("Hello", value), # hash of "Hello" is 9 > } > > So the positions of the keys in the table depend on the keys, not the > order you write them down. The advantage of this is that looking for a > key requires (near enough to) constant time. If you want to see whether > "Eggs" is in the table, it doesn't matter whether there are ten keys or > ten billion, it will take exactly the same amount of time: hash the key > "Eggs" to give you index 5, look at index 5, it is either there or it > isn't. > > Now, in reality we can't actually guarantee that every hash value is > distinct. In real life, a hash table has to deal with "collisions", > which is when two different keys have the same hash value, and that will > spoil the nice simple constant time performance. But collisions are > usually rare, and so when discussing hash tables in broad terms we > normally ignore them. > > In Python, you can calculate the hash value of a key with the hash() > function. The exact values you get may depend on the specific version of > Python
Re: [Tutor] minor display issue with python dictionaries
On Sun, Nov 24, 2013 at 8:22 PM, Joel Goldstick wrote: > On Sun, Nov 24, 2013 at 8:12 PM, Steven D'Aprano wrote: >> On Sun, Nov 24, 2013 at 09:33:11PM +0530, Reuben wrote: >> [...] >>> From the above output, I see key 'c' is at third position during input, but >>> while displaying the output it is displayed at second position >> >> Dictionaries are deliberately made unordered. That means the order that >> items will be displayed is free to vary, not only from how you entered >> them, but in principle they might even vary each time you inspect the >> dict. (They probably won't, but they could.) >> >> Python dicts are actually "hash tables", which is a standard computer >> science data structure that you can look up, but in a nutshell, a hash >> table is an array indexed by the key's hash value. Why do we care about >> hash tables? Because they make a really fast and efficient way to look >> up keys, and from the key get access to a value. >> >> Let's start with the simplest way to store a key and value pair, an >> unsorted table of pairs with a marker indicating "blank", so you know >> when you've reached the end. Here's an example of a half-filled table: >> >> { ("Hello", value), # key first, then some value >> ("World", value), >> ("Spam", value), >> ("Eggs", value), >> ("Cheese", value), >> , >> , >> , >> , >> , >> } >> >> In order to find a key in the table, you have to inspect every position >> until you reach either the key you are looking for, or , in which >> case you know that the key is not there. So to find "Eggs", you have to >> inspect "Hello", "World", "Spam" and finally "Eggs". On average, a >> successful search takes half as many inspections as there are keys, e.g. >> if you have 10 keys in the table, you need to inspect 5 positions; if >> there are 100 keys, you need to inspect 50 positions on average. If >> there are 1000 keys, you need to inspect 500 positions. >> >> This is pretty slow. Imagine looking up a word in a dictionary (a real >> paper dictionary), but with a twist: the words are in whatever order the >> dictionary writer first thought of them, not alphabetical order, so for >> any word you have to start at the beginning and read every single world >> until you find it. >> >> Obviously we can do better, by keeping the words sorted. Our table will >> look like this: >> >> { ("Cheese", value), >> ("Eggs", value), >> ("Hello", value), >> ("Spam", value), >> ("World", value), >> , >> , >> , >> , >> , >> } >> >> In this case, we can use a technique called "binary search" to narrow >> down the possible places the key might be. This is very much like what >> you probably do when looking up words in a paper dictionary: flip the >> dictionary open to the middle, then decide whether you've gone too far >> or not far enough. Each time, you split the remaining half in half >> again, until you've narrowed down to the page containing the word you >> want. >> >> In a sorted table with binary search, the savings over an unsorted table >> can be very high. With 10 keys, on average you will end up inspecting 3 >> or 4 items, which isn't much improvement over 5 for the unsorted case, >> but with 100 keys, you will inspect 6 or 7, and with 1000 keys, 9 or 10. >> With a million keys, you only need to inspect about 20 items to either >> find the key you are looking for, or determine it isn't there. >> >> Can we do better than binary search? Yes we can, and we do so with a >> hash table, which is what Python dicts are. >> >> The secret to the hash table is that instead of putting all the keys at >> the beginning of the table, we want the entries to be scattered at >> random all over the place. Only not quite at random, since we need a way >> to jump straight to the key when asked. That's the *hash function*, >> which converts a key to an arbitrary, and distinct, index: >> >> { , >> ("World", value), # hash of "World" is 1 >> ("Cheese", value), # hash of "Cheese" is 2 >> , >> , >> ("Eggs", value),# hash of "Eggs" is 5 >> , >> ("Spam", value),# hash of "Spam" is 7 >> , >> ("Hello", value), # hash of "Hello" is 9 >> } >> >> So the positions of the keys in the table depend on the keys, not the >> order you write them down. The advantage of this is that looking for a >> key requires (near enough to) constant time. If you want to see whether >> "Eggs" is in the table, it doesn't matter whether there are ten keys or >> ten billion, it will take exactly the same amount of time: hash the key >> "Eggs" to give you index 5, look at index 5, it is either there or it >> isn't. >> >> Now, in reality we can't actually guarantee that every hash value is >> distinct. In real life, a hash table has to deal with "collisions", >> which is when two different keys have the same hash value, and that will >> spoil the nice simple constant time performance. But collisions are >> usually rare, and so when discussing hash tables in broad terms we >> normally
Re: [Tutor] Else vs. Continue
On Sun, Nov 24, 2013 at 10:32:20PM +0100, Rafael Knuth wrote: > Hej there, > > I stumbled upon the "continue" statement and to me it looks like it > does exactly the same as else. I tested both else and continue in a > little program and I don't see any differences between both. "continue" and "else" are completely unrelated. "continue" can only be inside a for-loop or a while-loop, and it immediately jumps back to the beginning of the next loop. If I write this: for i in range(10): print(i) continue print("This will never be printed") it will print the numbers 0 through 9 but never reach the second print. Obviously, unconditionally using "continue" in this way is silly. If you don't ever want the second print line, why not just leave it out? But it is useful to conditionally continue or not, which means you will nearly always see "continue" somewhere inside an if...elif...else block. For example: for i in range(20): if i%2 == 0: print("Skipping an even number") continue print("Odd number {}".format(i)) print("Remainder when divided by three is: {}".format(i%3)) The continue need not be inside the "if" block. It could be inside an "elif" or "else" block instead. -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Depth First Search Listing all possible combinations
You have at least one error in your graph. Specifically, if you are using: ### graph = {'q9': ['q10', 'q33'], 'q10': ['q11', 'q 28', 'q29', 'q30'], 'q11': ['q15'] , 'q16': ['q17', 'q19', 'q24'],' q18': ['q20'], 'q23': ['q34'], 'q24': ['q25', 'q26'], 'q27': ['q34'], 'q28': ['q30', 'q29'], 'q30': ['q34', 'q31', 'q12'], 'q32': ['q34'], 'q33': ['q15' , 'q30'], 'q35': ['q36', 'q37'], 'q37': ['q38', 'q39'], 'q39': ['q41', 'q40', 'q42'],'q42': ['end']} ### to represent the graph structure you've presented, then 'q15' is missing. Other nodes in your network may also be missing, so check your data again. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor