0

2 つの非常に長いテキスト ファイル (1 行に 1 つずつ、数千の電子メール アドレス) があり、2 つのファイルを比較して、最初のファイルと 2 番目のファイルに含まれるアドレスを出力する方法を探していますが、両方ではありません (集合論の AUB/(A⋂B) のようなもの)。このように、文字列を含むリストを入力として使用できれば、非常に簡単です。

input1=['address1','address2',...,'addressn']

しかし、私のテキスト ファイルは長く、異なる行にあるため、手動で各アドレスを「. そこで、すべてのアドレスをスペースで区切った単一の文字列を入力として使用し、それを文字列のリストに変換しようとしました。これは私が出てきたものです:

import numpy as np
from StringIO import StringIO

def conv(data):
    array1=np.genfromtxt(StringIO(data),dtype="|S50")
    lista1=[]
    for el in array1:
        lista1.append(el)
    return lista1

input1='address1 address2 ... addressn'

そして、これは私が関数を呼び出すときに得られるものです

>conv(input1)
>['address1', 'address2', 'addressn']

それは機能しますが、問題があります。入力は水平にする必要があるため、テキストファイルからアドレスをコピーして文字列に貼り付けることはできません。

input1="Davide
...:Michele
...:Giorgio
...:Paolo"

File "<ipython-input-4-6d70053fb94e>", line 1
  input1="Davide
             ^
SyntaxError: EOL while scanning string literal

どうすればこの問題に対処できますか? コードを改善するための提案は非常に高く評価されます。私は StringIO モジュールについてほとんど何も知りませんが、今日初めてそれに出会いました。私よりもはるかに効率的なプログラムを作成できると確信しています。ちなみに、これはプログラム全体です:

def scan(data1,data2): #Strings
    array1=np.genfromtxt(StringIO(data1),dtype="|S50")
    array2=np.genfromtxt(StringIO(data2),dtype="|S50")
    lista1=[]
    lista2=[]
    for el in array1:
        lista1.append(el)
    for el in array2:
        lista2.append(el) #lista1 and lista2 are lists containing strings
    num1,num2=len(lista1),len(lista2)
    shared=[]
    for el in lista1:
        if el in lista2:
            shared.append(el) #shared is the intersection of lista1 and lista2
    if len(shared)==0:
        print 'No shared elements'
        return lista1+lista2
    else:
        for el in shared:
            n1=lista1.count(el)
            for i in range(n1):
                lista1.remove(el) #Removes from lista1 the elements shared with lista2
            n2=lista2.count(el)   #as many times as they appear
            for j in range(n2):
                lista2.remove(el) #Removes from lista2 the elements shared with lista1
    result=lista1+lista2          #as many times as they appear
    print 'Addresses list 1:',num1
    print 'Addresses list 2:',num2
    print 'Useful Addresses:',len(list(set(result)))
    return (list(set(result)))

これがどのように機能するかの例です。

data1="Davide John Kate Mary Susan"
data2="John Alice Clara Kate John Alex"
scan(data1,data2)
>Addresses list 1: 5
>Addresses list 2: 6
>Useful Addresses: 6
>['Alex', 'Susan', 'Clara', 'Alice', 'Mary', 'Davide']

手伝ってくれてありがとう :)

4

3 に答える 3

1

複数行にまたがる文字列を三重引用符で囲みます。

input1="""Davide
...:Michele
...:Giorgio
...:Paolo"""

それらはリターン ( "\n") で区切られるので、リストに変換するために使用できますinpu1.split('\n')

セット オブジェクトを使用すると、操作が非常に簡単になります。s1にない要素を取得するには、s2単純に を実行できますs1 - s2。ユニオンは公正|であり、インターセクションはまさに&そうです。

s1 = set(input1.split('\n'))
s2 = set(input2.split('\n'))
adresses_in_only_one_file = (s1 | s2) - (s1 & s2)
于 2014-05-03T23:46:54.683 に答える
0
shared =[]
for el in lista1:
    if el in lista2:
        shared.append(el) #shared is the intersection of lista1 and lista2

In [10]: lista1=[1,2,3,4,5,6,7,8,9]

In [11]: lista2=[1,2,3,10,11,12,13]

In [12]: lista1=set(lista1)

In [13]: shared = lista1.intersection(lista2) # same as your loop above

In [14]: shared
Out[14]: {1, 2, 3}

リストが必要な場合は、使用してくださいlist(lista1.intersection(lista2))

for el in shared:
    n1=lista1.count(el)
    for i in range(n1):
        lista1.remove(el) #Removes from lista1 the elements shared with lista2
    n2=lista2.count(el)   #as many times as they appear
    for j in range(n2):
        lista2.remove(el)
result=lista1+lista2

         lista1=set(lista1) 
In [15]: list(lista1.symmetric_difference(lista2))
Out[15]: [4, 5, 6, 7, 8, 9, 10, 11, 12, 13] # same as above.
于 2014-05-04T10:37:01.110 に答える