Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
maskenfreiheit
Dec 30, 2004
Edit: doublepost

maskenfreiheit fucked around with this message at 01:21 on Mar 13, 2017

Adbot
ADBOT LOVES YOU

chips
Dec 25, 2004
Mein Führer! I can walk!

GregNorc posted:

So I'm trying to create a function that returns True if the list is already orted, and false if it isn't.

This is how I planned to do it:
[code]test = ['a', 'c', 'd', 'b', 'e']
def is_sorted(list):
if list == list.sort()
return True
else:
return False

is_sorted(test)[code]

I did some tests in the interpreter and found the problem:


Nothing I've tried to fix this works. I really would like to store the result of list.sort in a list of its own, so I could just compare the two... if they're identical then the original must be sorted.

If anyone knows what I'm doing wrong, I'd appreciate a hint.

Wouldn't it be faster to check if the list is sorted in O(n) time (i.e. a single loop pass), rather than sorting it and comparing, taking O(n log n) time?

Also, calling a function requires (), otherwise you're just expressing the function object.

i.e. if you have a function def f(): return 1

a = f
b = f()

a contains the "value" of the function f, b contains the value 1.

tef
May 30, 2004

-> some l-system crap ->
x.sort() returns None. sorted(x) returns a sorted copy of the list.


if x.sort() returned the sorted list, your method would be a little odd. .sort() changes the list in place.


edited to add: "I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."

code:
>>> a = [1,3,5,3,2,1]
>>> b = [1,2,3,4,5,6]
>>> def is_sorted(x):
...     return x == sorted(x)
... 
>>> is_sorted(a)
False
>>> is_sorted(b)
True
edited to add again:
code:
>>> is_sorted_asc = lambda x:sum(a>b for a,b in zip(x[:-1],x[1:])) == 0
>>> is_sorted_asc([1,2,3,4])
True
>>> is_sorted_asc([1,2,3,4,-1])
False

tef fucked around with this message at 01:42 on Dec 24, 2009

MaberMK
Feb 1, 2008

BFFs

chips posted:

Wouldn't it be faster to check if the list is sorted in O(n) time (i.e. a single loop pass), rather than sorting it and comparing, taking O(n log n) time?

Also, calling a function requires (), otherwise you're just expressing the function object.

i.e. if you have a function def f(): return 1

a = f
b = f()

a contains the "value" of the function f, b contains the value 1.

Yes.

Regardless, unless you're working with huge amounts of data and you don't know anything about the ordering but there's a good chance the data is already sorted (I can't think of a situation in which these circumstances would arise), it's better to just assume the list isn't sorted and sort it. It's kind of pointless to check to see if a list is sorted because if it isn't, you'll have to sort it anyway.

MaberMK fucked around with this message at 01:41 on Dec 24, 2009

maskenfreiheit
Dec 30, 2004
Edit: doublepost

maskenfreiheit fucked around with this message at 01:21 on Mar 13, 2017

MaberMK
Feb 1, 2008

BFFs

GregNorc posted:

[insert facepalm here]

Thanks a lot!

Don't get carried away, read tef's post. As he pointed out, calling x.sort() will sort x and return None. sorted(x) will return x, sorted.

maskenfreiheit
Dec 30, 2004
...

maskenfreiheit fucked around with this message at 06:21 on Feb 19, 2010

chips
Dec 25, 2004
Mein Führer! I can walk!
That question does indicate that you should probably not be using the .sort() or sorted() functions, but rather loop through and check that each element is in order. It is more efficient to do it that way, though it would work with the given conditions to do your method. Also since your code will be in python and sort() is presumably in C, it might be slower for any reasonable number of elements anyway.

Sylink
Apr 17, 2004

Does python have an easy way to make dictionaries with many to one mapping?

Like (çookies,milk,reindeer) -> santa but if i call cookies or whatever by itself it returns santa

chips
Dec 25, 2004
Mein Führer! I can walk!
code:
santa = Santa()
d = {'cookies': santa, 'milk': santa, 'reindeer': santa}
So now every entry in the dictionary d points to the same santa object. Is that what you wanted? It might be useful to learn how Python names work.

bitprophet
Jul 22, 2004
Taco Defender

Sylink posted:

Does python have an easy way to make dictionaries with many to one mapping?

Like (çookies,milk,reindeer) -> santa but if i call cookies or whatever by itself it returns santa

Chips' approach will work for reading but will break once you reassign to any single item, which I'm guessing you don't want? It's pretty easy to subclass dict to make it work this way; check out the docs for __setitem__ and __getitem__. Main issue is that you'd need to add a mechanism for telling these dict-like objects what keys are to be tied together in this way, e.g. myinstance.link_keys('cookies', 'milk', 'reindeer').

Scaevolus
Apr 16, 2007

bitprophet posted:

Chips' approach will work for reading but will break once you reassign to any single item, which I'm guessing you don't want? It's pretty easy to subclass dict to make it work this way; check out the docs for __setitem__ and __getitem__. Main issue is that you'd need to add a mechanism for telling these dict-like objects what keys are to be tied together in this way, e.g. myinstance.link_keys('cookies', 'milk', 'reindeer').
Have it store references to items, so if you want to change the value for the group of common keys, you just change the reference.

Sylink
Apr 17, 2004

chips posted:

code:
santa = Santa()
d = {'cookies': santa, 'milk': santa, 'reindeer': santa}
So now every entry in the dictionary d points to the same santa object. Is that what you wanted? It might be useful to learn how Python names work.

That defeats the purpose of not having to type dozens of different individual entries in a dictionary which is why I wanted a many to one method in the first place.

ShoulderDaemon
Oct 9, 2003
support goon fund
Taco Defender

Sylink posted:

That defeats the purpose of not having to type dozens of different individual entries in a dictionary which is why I wanted a many to one method in the first place.

Show us the syntax you want to be legal, and we'll show you how to write a function that gets you close to that syntax. It's not clear what you are imagining, and that's why people aren't answering your question.

chips
Dec 25, 2004
Mein Führer! I can walk!
How else would you express many-to-one? Having a "linked" mechanism doesn't add anything over references as you still need to be able to remap one of a currently linked set to an unrelated item. Any many-to-one collection must ultimately be a dictionary of references as I described, since you still have to explicitly specify each item.

Linking 'b' to 'a' is just

code:
d['b'] = d['a']
Then you can remap 'b' to something else later on

code:
d['b'] = Blah()
You could write a function (or a new method of a dictionary) which does something like

code:
def assign_many(d, xs, value):
    for x in xs:
        d[x] = value
So you can do (if it was a new method of a dictionary) d.assign_many(('cookies','milk','reindeer'),santa)

maskenfreiheit
Dec 30, 2004
Edit: doublepost

maskenfreiheit fucked around with this message at 01:21 on Mar 13, 2017

Glyn
Feb 8, 2005

Everyone wants to be Cary Grant. Even I want to be Cary Grant.
I think the problem is that pop() works like a queue, not like a loop.

Try this:
code:
def remove_duplicates(list):
        dups = []
        for item in list:                
            if item not in dups:
                dups.append(item)
        return dups

maskenfreiheit
Dec 30, 2004
Edit: doublepost

maskenfreiheit fucked around with this message at 01:21 on Mar 13, 2017

ShoulderDaemon
Oct 9, 2003
support goon fund
Taco Defender

GregNorc posted:

It should output 3 and 4 (the only two which repeat)

This is not what "only the unique elements in a list" means. If you're doing exercise 10.6 from Think Python, then Glyn's solution is correct.

maskenfreiheit
Dec 30, 2004
Edit: doublepost

maskenfreiheit fucked around with this message at 01:21 on Mar 13, 2017

Scaevolus
Apr 16, 2007

GregNorc posted:

This one is supposed to be a function that takes a list, and returns a new list consisting of only the unique elements from the original list.

code:
def remove_duplicates(lst):
    return list(set(lst))
:haw:

king_kilr
May 25, 2007

Scaevolus posted:

code:
def remove_duplicates(lst):
    return list(set(lst))
:haw:

Doesn't maintain order. :colbert:

Edit:

O(n) solution is

code:
from collections import Counter


def remove_duplicates(lst):
    items = Counter(lst)
    return [x for x in lst if items[x] > 1]
Edit 2:

That returns duplicate items. Removing those is an excersise to the reader :D

king_kilr fucked around with this message at 06:35 on Dec 26, 2009

Scaevolus
Apr 16, 2007

king_kilr posted:

Doesn't maintain order. :colbert:
Problem statement doesn't mention order. :smugbert:

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

The unique items thing reminds me of one of the first things I ever did in Python that I thought at the time was clever of me.

code:
l = [1,2,3,3,4,5,5]
dupes_removed = list(dict.fromkeys(l))

tripwire
Nov 19, 2004

        ghost flow

Thermopyle posted:

The unique items thing reminds me of one of the first things I ever did in Python that I thought at the time was clever of me.

code:
l = [1,2,3,3,4,5,5]
dupes_removed = list(dict.fromkeys(l))

Heh, that is a little clever. I used the same technique for making a list of the distinct colours (as rgb tuples) in an image before I learned how sets worked in python.

king_kilr
May 25, 2007

Scaevolus posted:

Problem statement doesn't mention order. :smugbert:

Well maybe it should have /last word :D

Sylink
Apr 17, 2004

My current project is going to require a GUI.

Can anyone recommend good GUI modules for python? They can be windows only, I just want something simple and easy to make some text boxes and get input from them.

I don't really like Tkinter but I wanted a different opinion.

Scaevolus
Apr 16, 2007

Sylink posted:

My current project is going to require a GUI.

Can anyone recommend good GUI modules for python? They can be windows only, I just want something simple and easy to make some text boxes and get input from them.

I don't really like Tkinter but I wanted a different opinion.

PyQt or wxPython. I prefer PyQt.

jupo
Jun 12, 2007

Time flies like an arrow, fruit flies like a banana.
I haven't tried PyQt myself but I've used wxPython on a few projects and it worked really well. I picked it up easily using this tutorial

Ferg
May 6, 2007

Lipstick Apathy
I like PyGTK though it's a little trickier to get up and running on Windows.

king_kilr
May 25, 2007
I like the PyGTK API best, but it's not so fun (or pretty) for windows users.

Ferg
May 6, 2007

Lipstick Apathy

king_kilr posted:

I like the PyGTK API best, but it's not so fun (or pretty) for windows users.

It can be if you install Pidgin, or whatever version of GTK comes with it. It gets you a bunch of decent themes. I use Clearlooks on Windows, which really pretties up the handful of PyGTK-based tools I've built and use on a day-to-day basis.

maskenfreiheit
Dec 30, 2004
Edit: doublepost

maskenfreiheit fucked around with this message at 01:21 on Mar 13, 2017

nbv4
Aug 21, 2002

by Duchess Gummybuns

GregNorc posted:

So I am in the think python chapter on tuples.

Sum by dault takes two values. So for example, sum(1, 2) returns 3, but sum(1, 2, 3) gives an error.

I'm trying to make a version of sum that takes more than two values.

I made this code that should be able to take any arbiraty amount of input and sum it, but when I run it I get an error that:



Here's the code:

code:
def sum_all(*args):
	total = 0
	i = 0
	length = len(args)
	while i < length:
		total = sum(args[i], total)	
		i += 1
	return total	
print sum_all(1, 2, 3)
This is really confusing me... I know tuples are immutable, but I am not modifying the tuple.

But what this should be doing is that it reads the value of the tuple, say args[0]. It sums it with the total, and that sum becomes the new "total".

Then we increment the counter (i) by one... and keep going, until i is at the length of the tuple.

I _NEVER_ modify he tuple. NEVER.

Instead I take it's value, and add that value to something else, which should be perfectly legal. I am completely lost... the book I'm using considers this simple enough to not require a posted solution, but I have no clue how to change the program so it's legal.

you aren't using the sum function correctly, the first argument should be an iterable

http://docs.python.org/library/functions.html#sum

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

GregNorc posted:

Sum by dault takes two values. So for example, sum(1, 2) returns 3
No, it doesn't. It produces the exact same error as your function does, because that's not what sum does in python.

GregNorc posted:

This is really confusing me... I know tuples are immutable, but I am not modifying the tuple.

But what this should be doing is that it reads the value of the tuple, say args[0]. It sums it with the total, and that sum becomes the new "total".

Then we increment the counter (i) by one... and keep going, until i is at the length of the tuple.

I _NEVER_ modify he tuple. NEVER.

Instead I take it's value, and add that value to something else, which should be perfectly legal. I am completely lost... the book I'm using considers this simple enough to not require a posted solution, but I have no clue how to change the program so it's legal.
What makes you think your error is in any way related to modifying a tuple?

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
if you replace sum(i, total) with i + total it will work. As it is sum(args) will work as you intend. Further, there is no reason for a while loop here. Tuples are iterable.

Edit: if you're not trying this stuff out in the python shell, you're doing it wrong.

maskenfreiheit
Dec 30, 2004
Edit: doublepost

maskenfreiheit fucked around with this message at 01:22 on Mar 13, 2017

maskenfreiheit
Dec 30, 2004
Edit: doublepost

maskenfreiheit fucked around with this message at 01:22 on Mar 13, 2017

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.

quote:

Traceback (most recent call last):
File "ex12_1.py", line 9, in <module>
sum_all(1, 2, 3)
File "ex12_1.py", line 6, in sum_all
total = sum(args[i], total)
TypeError: 'int' object is not iterable

You need to learn to read these. It says your sum_all function was called and inside it an error happened on line 6 where you call sum. So you open up the interactive interpreter and try a few things until you get to sum(1, 2) and see that that is the error.

Adbot
ADBOT LOVES YOU

CoderCat
May 7, 2005

Science, it works. :science:

GregNorc posted:

code:
def sum_all(*args):
	total = 0
	i = 0
	length = len(args)
	while i < length:
		total = sum(args[i], total)	
		i += 1
	return total	
print sum_all(1, 2, 3)

Slightly unrelated, but you can iterate over items in a list using the for loop. It's shorter and easier:
code:
def sum_all(*args):
	total = 0
	for elem in args:
		total += elem
	return total	
print sum_all(1, 2, 3)
As others pointed out, the function can be simplified further by using sum correctly:

code:
def sum_all(*args):
	return sum(args)
print sum_all(1, 2, 3)

  • Locked thread