Usuwanie pojedynczych wartości

0

Witam. Posiadam kilka plików w których są wypisane pary kryptowalut np: USDTBTC. Wygląda to tak:

NULSBTC
NEOBTC
NULSETH
LINKBTC
IOTABTC
ETCBTC

NULSBNB
BNBBTC
NULSBTC
NEOBTC
NULSETH
LINKBTC
IOTABTC
ETCBTC

NULSBNB
BNBBTC
LINKBTC
IOTABTC
USDTBTC

Chodzi o to, że tylko raz występuje np.USDTBTC, więc chce to usunąć. Jeśli w tych zbiorach jest więcej niż 2 takie same wartości to zostawiam, jeśli jest tylko jedna na wszystkie zbiory to usuwam. Jak to zrobić? Pozdrawiam

0

Przeleć przez zbiory i zlicz ile czego masz. Np:

import collections
c = collections.Counter()
with open('your_file.txt', 'r') as f:
        c.update(f)

c będzie kontenerem (dictem) który zawiera informacje co ile razy występuje. Wyrzuć wszystko co występuje tylko raz i zostaw jako set(liczniki już nie potrzebne):

c_filtered = {x for x in c if c[x] > 1}

Następnie możesz przeglądać swój zbiór raz jeszcze i akceptować tylko te, które są w c_filtered:

for item in container:
    if item not in c_filtered:
        continue
    #do whatever 

Pisane z palca więc mogą być błędy w składni i logice ;)

0
data_sets = [['NULSBNB', 'BNBBTC','NULSBTC', 'NEOBTC', 'NULSETH', 'LINKBTC', 'IOTABTC', 'ETCBTC'], ['NULSBTC','NEOBTC','NULSETH','LINKBTC','IOTABTC','ETCBTC'], 
                ['NULSBNB','BNBBTC','LINKBTC','IOTABTC','USDTBTC']]

def get_logest_set(data_sets):
    longes_set_idx = 0
    max_set = 0
    for idx, item in enumerate(data_sets):
        if len(item) > max_set:
            longes_set_idx = idx
            max_set = len(item)
    return longes_set_idx
    
def create_template(logest_set):
    tmp = {}
    for item in logest_set:
        if item not in tmp.keys():
            tmp[item] = 1
        else:
            tmp[item] += 1
    return tmp
    
logest_data_set = get_logest_set(data_sets)
template = create_template(data_sets[logest_data_set])
data_cp = data_sets[:]
data_cp.pop(logest_data_set)
to_delete = []
for item in data_cp:
    for i in item:
        if i in template.keys():
            template[i] += 1
        else:
            template[i] = 1
        
for k, v in template.items():
    if v < 2:
        to_delete.append(k)
        
for idx, item in enumerate(data_sets):
    for i, data in enumerate(item):
        if item in to_delete:
            data_sets[idx].pop(i)
            
print(data_sets)
            

Tu masz baaaardzo po kolei tak dla zrozumienia jak co sie dzieje :)

0

Zakładając że chcesz to przechowywać w pliku w formie tekstowej, nie istnieje w pojęciu pliku coś takiego jak usuwanie jego treści, tylko nadpisanie go nową wersją bez fragmentów które są nam zbędne. Zakładając że będziesz robił to częściej i jesteś na etapie który jeszcze nie zaburzy całej pracy programu, lepiej zapisać strukturę w formacie JSON, albo za pomocą pickle.
Gdybyś stworzył strukturę z Flagami bitowymi, każda flaga odpowiada innemu 'plikowi', możesz selektywnie sobie wybierać te które znajdują się w chociaż dwóch plikach, suma flag bitowych w takich warunkach będzie większa od dwóch i różna od czterech. Wczytanie struktury, będzie efektywniejsze od parsowania pliku, zliczania elementów i tworzenia struktury liczącej za każdym razem. Równie szybko możesz odfiltrować te które potrzebujesz.

Jeśli nie możesz tego już zmienić, i chcesz po prostu usuwać pojedyńcze rekordy ze zbioru plików, to @AsterFV podał dość dobry sposób z jednym wyjątkiem, załóżmy że z każdego pliku chcemy 'usunąć' pojedyńcze wystąpienie, musimy więc wiedzieć w których plikach są pozostałe rekordy.
Najprostsze rozwiązanie jakie ja widzę:

def remove_unique_lines(filenames):
	files_container = {}
	for filename in filenames:
		with open(filename, "r") as f:
			files_container[filename] = f.read()

	for filename, text in files_container.items():
		with open(filename, "w") as f:
			for line in text:
				if count_from_iterable(files_container.values(), line) > 1:
					f.write(line)
        
def count_from_iterable(iter, search):
    counter = 0
    for elem in iter:
        counter += elem.count(search)
    return counter
    
if __name__ == "__main__":
	filenames = ("1.txt", "2.txt", "3.txt")
	remove_unique_lines(filenames)

Mogłem się gdzieś machnąć, ale mniej więcej podobnie do tego mogłoby to wyglądać :)
Da się to zrobić optymalniej:
-Nie przeszukiwać tekstu z którego bierzesz te linię.
Albo jeszcze lepiej:
-Zastosować counter jak kolega wyżej ale zapamiętując pliki które trzeba później przelecieć, a później tylko wyszukiwać ile razy w counterze znajduje się linia, wtedy ją zapisać lub nie zależnie od ilości wystąpień...

0
what=$(sort -- "$@" | uniq -d)
for file in "$@"; do
    mv -- "$file"{,.orig}
    grep -F -x -f <<<"$what" "$file.orig" >"$file"
done

1 użytkowników online, w tym zalogowanych: 0, gości: 1