naheed arafat | 1 May 05:23 2011
Picon

confusions about re module

someone please tell me why i'm getting this output?
specially the 'e3%' ! ! !
>>> import re
>>> re.findall('([\w]+.)','abdd.e3\45 dret.8dj st.jk')
['abdd.', 'e3%', 'dret.', '8dj ', 'st.', 'jk']

I am getting the same output for the following too..
>>> re.findall(r'([\w]+.)','abdd.e3\45 dret.8dj st.jk')
['abdd.', 'e3%', 'dret.', '8dj ', 'st.', 'jk']

wasn't i supposed to get ['abdd.','dret.'] ??
python version: 2.6.5
os: windows

_______________________________________________
Tutor maillist  -  Tutor <at> python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Ryan Strunk | 1 May 05:49 2011
Picon

Combining two Dictionaries

Hello everyone,

I had an interesting thing come up earlier in my programming, and I'm trying
to wrap my mind around why it occurred.
I wanted to take two dictionaries with the same keys and combine their
values to make one, big super dictionary.

def combine(d1, d2):
    for key in d1:
        if key in d2:
            d2[key] += d1[key]

When I assign values to each dictionary, this works perfectly.
d1 = {'a': 1, 'b': 2, 'c': 3}
d2 = {'a': 10, 'b': 20, 'c': 30}
combine(d1, d2)
d1 = {'a': 1, 'b': 2, 'c': 3}
d2 = {'a': 11, 'b': 22, 'c': 33}

When I initialize the class which holds these dictionaries, though, I need
to make sure that all the keys contained in d2 match the keys of d1. Thus I
tried:
d1 = {'a': 0, 'b': 0, 'c': 0}
d2 = d1
My understanding was that d2 looked at d1 once, grabbed its keys and values,
and went off to do its own thing.  Just as if you typed:
x = 3
y = x
x = 6
y still holds the value 3.
This turns out not to be the case with dictionaries, and I'm not sure why
this is so. Why when you change a dictionary's keys in place does a copied
dictionary take on the new values?
Thanks for any help you can provide.

Best,
Ryan

_______________________________________________
Tutor maillist  -  Tutor <at> python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Knacktus | 1 May 06:46 2011

Re: Combining two Dictionaries


>
> def combine(d1, d2):
>      for key in d1:
>          if key in d2:
>              d2[key] += d1[key]

[Remark]
I usually avoid changing function arguments. But later on you're talking 
about using this function as a method a class, so d1 and d2 would be 
instance attributes I guess.

> When I initialize the class which holds these dictionaries, though, I need
> to make sure that all the keys contained in d2 match the keys of d1. Thus I
> tried:
> d1 = {'a': 0, 'b': 0, 'c': 0}

Now d1 holds the address of a dict in memory. The dict contains your data.

> d2 = d1

Now d2 holds the same address of the same dict in memory. d1 and d2 
refer to the same dictionary.

> My understanding was that d2 looked at d1 once, grabbed its keys and values,
> and went off to do its own thing.

You would need to use copy() explicitly.

import copy

d2 = copy.copy(d1) # swallow copy

# or a deep copy
# -> copies also referenced objects recursively
# usefull if you have e.g. lists as values in your dict
# and want them copied too.

d2 = copy.deepcopy(d1)

  Just as if you typed:
> x = 3
> y = x
> x = 6
> y still holds the value 3.

Python has mutable and immutable types. Str and int, for example, are 
immutable. Dicts and list for example are mutable.
The statement x=6 binds x to a new object, because the object with value 
3 cannot be changed.

There are a lot of  explanations about mutable and immutable types. Much 
better then I could. You could search the list, for example here: 
http://dir.gmane.org/gmane.comp.python.tutor
or the web or see this overview in the docs:
http://docs.python.org/reference/datamodel.html#objects-values-and-types

Generally, I wouldn't copy an existing dict to make sure the other dict 
has the same values. The data must come from somewhere. I would check 
the data, then you wouldn't need to check the container.

Finally, you could use dict.get with a default set to 0, then you 
wouldn't need to care, e.g. (using dict comprehension and creating a new 
dict):

def combine_2(d1, d2):
     return {key: d1[key]+d2.get(key, 0) for key in d1}

But that's a bit dirty semantic wise, better to check the input data ... 
just to show you the syntax.

HTH,

Jan

_______________________________________________
Tutor maillist  -  Tutor <at> python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Andre Engels | 1 May 07:29 2011
Picon

Re: Combining two Dictionaries

On Sun, May 1, 2011 at 5:49 AM, Ryan Strunk <ryan.strunk <at> gmail.com> wrote:

> When I initialize the class which holds these dictionaries, though, I need
> to make sure that all the keys contained in d2 match the keys of d1. Thus I
> tried:
> d1 = {'a': 0, 'b': 0, 'c': 0}
> d2 = d1
> My understanding was that d2 looked at d1 once, grabbed its keys and values,
> and went off to do its own thing.  Just as if you typed:
> x = 3
> y = x
> x = 6
> y still holds the value 3.
> This turns out not to be the case with dictionaries, and I'm not sure why
> this is so. Why when you change a dictionary's keys in place does a copied
> dictionary take on the new values?
> Thanks for any help you can provide.

To answer your question, we have to look at Python's data model, which
differs from that in other languages. What

y = x

does, is to calculate the object x and give it the name y, apart from
whatever names it may or may not have already. Thus, it does _not_
make a copy, but x and y are two different names of the _same_ object.
What happens in your example, is that you give the object 3 the name
x, then give the object 3 (the outcome of the 'calculation' x) the
name y, then give the object 6 the name x. After that y is still a
name for 3. But if you're working with dictionaries, you're probably
doing something like this:

d1 = {'a': 0, 'b': 0, 'c': 0}  # You create a dictionary and give it the name d1
d2 = d1 # You give _the same_ dictionary the name d2
d1['c'] = 1 # You _change_ the dictionary by changing its value for
the key c. d1 and d2 still are names for the _same_ dictionary

Just like in the integer situation, d2 is still a name for the same
object as it was before, but this time _the object itself has
changed_. And d2 'sees' the change of the object.

--

-- 
André Engels, andreengels <at> gmail.com
_______________________________________________
Tutor maillist  -  Tutor <at> python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Peter Otten | 1 May 09:14 2011
Picon

Re: confusions about re module

naheed arafat wrote:

> someone please tell me why i'm getting this output?
> specially the 'e3%' ! ! !
>>>> import re
>>>> re.findall('([\w]+.)','abdd.e3\45 dret.8dj st.jk')
> ['abdd.', 'e3%', 'dret.', '8dj ', 'st.', 'jk']
> 
> I am getting the same output for the following too..
>>>> re.findall(r'([\w]+.)','abdd.e3\45 dret.8dj st.jk')
> ['abdd.', 'e3%', 'dret.', '8dj ', 'st.', 'jk']
> 
> wasn't i supposed to get ['abdd.','dret.'] ??
> python version: 2.6.5
> os: windows

Quoting http://docs.python.org/library/re.html :

"""
'.'
(Dot.) In the default mode, this matches any character except a newline. If 
the DOTALL flag has been specified, this matches any character including a 
newline.

[...]

'\'
Either escapes special characters (permitting you to match characters like 
'*', '?', and so forth), or signals a special sequence; special sequences 
are discussed below.
"""

So you get the desired behaviour by escaping the dot:

>>> re.findall(r'([\w]+\.)','abdd.e3\45 dret.8dj st.jk')
['abdd.', 'dret.', 'st.']
>>> re.findall(r'([\w]+[.])','abdd.e3\45 dret.8dj st.jk')
['abdd.', 'dret.', 'st.']

(assuming that you left out the last match accidentally)

_______________________________________________
Tutor maillist  -  Tutor <at> python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Steven D'Aprano | 1 May 10:28 2011

Re: Combining two Dictionaries

Knacktus wrote:

>> When I initialize the class which holds these dictionaries, though, I 
>> need
>> to make sure that all the keys contained in d2 match the keys of d1. 
>> Thus I
>> tried:
>> d1 = {'a': 0, 'b': 0, 'c': 0}
> 
> Now d1 holds the address of a dict in memory.  [...]

Let me guess... did you learn C before learning Python? Trust me, d1 
does not hold the address of anything. Try it and see for yourself:

 >>> d1 = {'a': 0, 'b': 0, 'c': 0}
 >>> print d1
{'a': 0, 'c': 0, 'b': 0}

Does that look like a memory address to you? Just to be sure:

 >>> type(d1)
<type 'dict'>

d1 holds a dict, as expected.

Forget about addresses. This isn't C, or assembly language. All that 
low-level stuff about address and memory locations has nothing to do 
with Python code and just confuses issues. You can't access memory 
addresses in pure Python code. Python abstracts all those low-level 
details away, and just cares about objects and names, in the same way 
that languages like C abstracts away the only operation a computer 
really can do: flip bits on or off.

(However, it is sometimes useful when thinking about the implementation 
of the Python virtual machine.)

>> d2 = d1
> 
> Now d2 holds the same address of the same dict in memory. d1 and d2 
> refer to the same dictionary.

No, and yes. d1 and d2 are two names for the same object:

 >>> d2 is d1
True

>> My understanding was that d2 looked at d1 once, grabbed its keys and 
>> values,
>> and went off to do its own thing.
> 
> You would need to use copy() explicitly.
> 
> import copy
> 
> d2 = copy.copy(d1) # swallow copy

I think you mean "shallow" copy.

You can do that, but for dicts there is a much simpler way to make a copy:

 >>> d3 = d1.copy()
 >>> d3 is d1
False
 >>> d3 == d1
True

--

-- 
Steven
_______________________________________________
Tutor maillist  -  Tutor <at> python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

naheed arafat | 1 May 10:48 2011
Picon

Re: confusions about re module

ya.you'r right. left it accidentally.thanks.


_______________________________________________
Tutor maillist  -  Tutor <at> python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Steven D'Aprano | 1 May 14:00 2011

Re: Combining two Dictionaries

Andre Engels wrote:

> To answer your question, we have to look at Python's data model, which
> differs from that in other languages.

Strictly speaking, that is true: Python's data model is different from 
that of (say) C, or Pascal, or Forth. But it's also the same as that in 
other languages, like Ruby, and Java (mostly), and others.

--

-- 
Steven

_______________________________________________
Tutor maillist  -  Tutor <at> python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Greg Christian | 1 May 20:28 2011
Picon
Picon

Compound if statement question.

Is there a way to write an if statement that will pick up duplicates (two ‘1’s):
 
L = ['1', '4', '1']
if (L[0]) != (L[1]) != (L[2]):
    print "THEY ARE NOT EQUAL"
else:
    print "THEY ARE EQUAL"
 
When I run this code, it prints “THEY ARE NOT EQUAL” when it should print the else “THEY ARE EQUAL”.
 
list L has two ‘1’s; therefore I am trying to get an if statement that will recognize this. When using the != (not equal) operator, shouldn’t the if be true when items in list are not the same? Any input would be appreciated.
 
Thanks,
 
Greg
_______________________________________________
Tutor maillist  -  Tutor <at> python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Corey Richardson | 1 May 20:52 2011

Re: Compound if statement question.


On 05/01/2011 02:28 PM, Greg Christian wrote:
> Is there a way to write an if statement that will pick up duplicates (two ‘1’s):
> 
> L = ['1', '4', '1']
> if (L[0]) != (L[1]) != (L[2]):
>     print "THEY ARE NOT EQUAL"
> else:
>     print "THEY ARE EQUAL"
> 
> When I run this code, it prints “THEY ARE NOT EQUAL” when it should print the else “THEY ARE EQUAL”.
> 

Well, think about what that if-statement is doing. It's making sure that
the first three elements of L aren't equal to each other. Due to
python's short-circuit evaluation, it breaks the if after the first one,
because '1' != '4'. The parentheses there are useless.

You might look at [1] to see if there is anything that will count how
many times something appears in a list...

[1] -- http://docs.python.org/tutorial/datastructures.html#more-on-lists

--

-- 
Corey Richardson

Gmane