omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    Contacts what are the person objects?

    Pythonista
    namedtuple contacts person
    2
    4
    3589
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Phuket2
      Phuket2 last edited by

      I am confused about the person objects returned by the Contacts module. I came across this issue because I was trying to make a dataset class. I thought I should harmonise the data once read in from the source. So I thought translate the data to namedtuples. Rightly or wrongly, could have been another format. But I am guessing contacts.person is a little different. Maybe it just uses slots, I am not sure. Anyway, I went the long way around and converted the list of contacts to namedtuples. But it's slow on my iPad Pro. I have 992 contacts.
      Any comments welcome. I just have a feeling I am missing something very basic here. Either speeding up the func to create a list of namedtuples or by passing it all together. Again, I am trying to get to one internal data structure format. In this case namedtuples. The idea is that data from other sources will be loaded from .json files, memory or whatever, but will land in a nice format internally.

      Slow motion code

      import ui, editor, contacts
      from collections import namedtuple
      
      def objlist_to_named_tp(obj_list, filter_list = []):
      	'''
      	objlist_to_named_tp:
      		Desc:
      			Convert a list of objects in to a list of namedtuples.
      		params
      			obj_list = list of objects. The objects in the list need to
      			be able to support __dir__ 
      			filter_list = exclude any attr that appears in this list
      		
      	'''
      	tup_list = []
      	for obj in obj_list:
      		d = {k:getattr(obj, k) for k in dir(obj) if not k.startswith('_') and k not in filter_list  and not callable(k)}
      		np= namedtuple('DataItem', d.keys())(**d)
      		tup_list.append(np)
      		
      	return tup_list
      	
      
      		
      if __name__ == '__main__':
      
      	lst =objlist_to_named_tp(contacts.get_all_people(), filter_list = 'vcard')
      	p = lst[0] 
      	print(p.first_name,p.last_name, p.birthday)
      	print('records=', len(lst))
      	print('*'*50)
      	#print(p._source)
      
      1 Reply Last reply Reply Quote 0
      • ccc
        ccc last edited by

        10 seconds --> 1 second on my iPad... The trick is to only define the namedtuple once (for the first person) instead of defining it over and over again for each person in the list.

        def objlist_to_named_tp(people, filter_list=None):
            filter_list = filter_list or []  # avoid default mutable arguements
            # See: http://docs.python-guide.org/en/latest/writing/gotchas
            fields = (field for field in dir(people[0]) if not field.startswith('_')
                      and field not in filter_list and not callable(field))
            np = namedtuple('DataItem', fields)
            return [np(**{field: getattr(person, field) for field in np._fields})
                    for person in people]
        
        
        Phuket2 2 Replies Last reply Reply Quote 1
        • Phuket2
          Phuket2 @ccc last edited by

          @ccc , perfect. Thanks again. I Had unwound the dict comprehension, I put it back because there was no notable difference, problem was I was focusing on the wrong thing. I also,had an idea my list param was bad. I remember it's come up here on the forum before. But thanks for the link. I went and read it. The reason for the filter is to have a generic function not just for contacts. In this case, the vCard attr just seemed a little extreme in size to carry around in memory if you don't need it. I still have a little more to do. I think I will need to flatten out the fields in the namedtuples. I will worry about that later. I am pretty sure I need to do that when creating the fields for the namedtuple and then remap them so to speak. The challenge will be doing it generically. But again, it might be smarter to deal with those issues in my dataset object.
          But on my iPad Pro your version is instant, my version 3 to 4 secs. Huge difference.

          1 Reply Last reply Reply Quote 0
          • Phuket2
            Phuket2 @ccc last edited by

            @ccc , out of interest, did you try your func without passing 'vcard' to the filter? Puts a big strain on the timing

            1 Reply Last reply Reply Quote 0
            • First post
              Last post
            Powered by NodeBB Forums | Contributors