On Wed, Nov 2, 2016 at 12:02 PM, Mikhail V <mikhail...@gmail.com> wrote:

> Actually even with ASCII (read for python 2.7) I would also be happy
> to have such function: say I just want to keep only digits so I write:
>
> digits = "0123456789"
> newstring = somestring.keep(digits)
>

well, with ascii, it's not too hard to make a translation table:

digits = "0123456789"

table = [(o if chr(o) in digits else None )for o in range(256)]

s = "some stuff and some 456 23 numbers 888"

s.translate(table)

'45623888'

but then there is the defaultdict way:

s.translate(defaultdict(*lambda*: *None*, {ord(c):c *for* c *in*
digits}.items()))

'45623888'
wasn't that easy? Granted, if you need to do this, you'd wrap it in a
function like Chris A. Suggested. But this really isn't easy or
discoverable -- it took me a fair bit of fidlding to get right, and I knew
I was looking for a defaultdict implementation.

Also:

In [43]: table

Out[43]:

defaultdict(<function __main__.<lambda>>,

            {48: '0',
             49: '1',
             50: '2',
             51: '3',
             52: '4',
             53: '5',
             54: '6',
             55: '7',
             56: '8',
             57: '9'})

In [44]: s.translate(table)

Out[44]: '45623888'

In [45]: table

Out[45]:

defaultdict(<function __main__.<lambda>>,

            {32: None,
             48: '0',
             49: '1',
             50: '2',
             51: '3',
             52: '4',
             53: '5',
             54: '6',
             55: '7',
             56: '8',
             57: '9',
             97: None,
             98: None,
             100: None,
             101: None,
             102: None,
             109: None,
             110: None,
             111: None,
             114: None,
             115: None,
             116: None,
             117: None})

defaultdict puts an entry in for every ordinal checked -- this could get
big -- granted, probaly nt a big deal with modern computer memory, but
still...

it might even be worth making a NoneDict for this:

class NoneDict(dict):
    """
    Dictionary implementation that always returns None when a key is not in
the dict,
    rather than raising a KeyError
    """
    def __getitem__(self, key):
        try:
            val = dict.__getitem__(self, key)
        except KeyError:
            val = None
        return val

(see enclosed -- it works fine with translate)

(OK, that was fun, but no, not really that useful)

Despite I can do it other way, this would be much simpler and clearer
> way to do it. And I suppose it is quite common task not only for me.
>

That's the key question -- is this a common task? If so, then whie there
are ways to do it, they're not easy nor discoverable.

And while some of the guiding principles of this list are:

"not every two line function needs to be in the standard lib"

and

"put it up on PYPi, and see if a lot of people find it useful"


It's actually kind of silly to put a single function up as a PyPi package
-- and I doubt many people will find it if you did.

-CHB


-- 

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R            (206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115       (206) 526-6317   main reception

chris.bar...@noaa.gov
class NoneDict(dict):
    """
    Dictionary implimentaton that always returns None when a key is not in the dict,
    rather than raising a KeyError
    """
    def __getitem__(self, key):
        try:
            val = dict.__getitem__(self, key)
        except KeyError:
            val = None
        return val


def test_basic():
    '''
    some simple tests
    '''

    test_dict = {'a': 23,
                 'b': 45,
                 }
    arbitrary_keys = [23, 'that', (1, 2, 3)]
    d = NoneDict(test_dict)

    # do the ones in there work:
    for key, val in test_dict.items():
        print("trying:", key, val)
        print(d[key])
        assert d[key] == val

    for key in arbitrary_keys:
        print("trying:", key)
        assert d[key] is None

    # did the dict length change?
    assert len(d) == len(test_dict)

    print("all tests pass")


def test_with_translate():
    """
    tests using a NoneDict with str.translate()
    """
    digits = "0123456789"
    # make a translate table:
    table = NoneDict({ord(c): c for c in digits})

    s = "some stuff and some 456 23 numbers 888"

    final = s.translate(table)

    for c in final:
        assert c in digits
    print("it works with translate")



if __name__ == "__main__":
    test_basic()
    test_with_translate()

_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to