diff options
| author | Jeffrey Finkelstein <jeffrey.finkelstein@gmail.com> | 2015-05-19 21:50:48 -0400 |
|---|---|---|
| committer | Jeffrey Finkelstein <jeffrey.finkelstein@gmail.com> | 2015-07-17 01:36:27 -0400 |
| commit | 2f70ad71c5c9bf5e1929f78fc5f0d25c397a7652 (patch) | |
| tree | 9a43d466411201f12c5e18d647d281640a023a7c /networkx/algorithms | |
| parent | 1bba0a9aaeac331d735247eb0ddad281f1b0d44e (diff) | |
| download | networkx-2f70ad71c5c9bf5e1929f78fc5f0d25c397a7652.tar.gz | |
Use peek(S) instead of next(iter(S)).
As of the date of this commit, there is no way to get an arbitrary
element of an iterable like a set without modifying it (for example, as
in `set.pop()`). The `peek()` function is more readable than writing
next(iter(S))
whenever an arbitrary element of an iterable is required.
Diffstat (limited to 'networkx/algorithms')
| -rw-r--r-- | networkx/algorithms/approximation/ramsey.py | 4 | ||||
| -rw-r--r-- | networkx/algorithms/cluster.py | 28 | ||||
| -rw-r--r-- | networkx/algorithms/components/connected.py | 3 | ||||
| -rw-r--r-- | networkx/algorithms/connectivity/connectivity.py | 5 | ||||
| -rw-r--r-- | networkx/algorithms/connectivity/stoerwagner.py | 16 | ||||
| -rw-r--r-- | networkx/algorithms/dag.py | 11 | ||||
| -rw-r--r-- | networkx/algorithms/euler.py | 30 | ||||
| -rw-r--r-- | networkx/algorithms/flow/capacityscaling.py | 8 | ||||
| -rw-r--r-- | networkx/algorithms/flow/preflowpush.py | 12 | ||||
| -rw-r--r-- | networkx/algorithms/minors.py | 18 | ||||
| -rw-r--r-- | networkx/algorithms/tests/test_minors.py | 5 | ||||
| -rw-r--r-- | networkx/algorithms/tests/test_simple_paths.py | 3 |
12 files changed, 81 insertions, 62 deletions
diff --git a/networkx/algorithms/approximation/ramsey.py b/networkx/algorithms/approximation/ramsey.py index 03535ce9..14a70429 100644 --- a/networkx/algorithms/approximation/ramsey.py +++ b/networkx/algorithms/approximation/ramsey.py @@ -7,6 +7,8 @@ Ramsey numbers. # All rights reserved. # BSD license. import networkx as nx +from ...utils import arbitrary_element + __all__ = ["ramsey_R2"] __author__ = """Nicholas Mancuso (nick.mancuso@gmail.com)""" @@ -26,7 +28,7 @@ def ramsey_R2(G): if not G: return (set([]), set([])) - node = next(G.nodes_iter()) + node = arbitrary_element(G) nbrs = nx.all_neighbors(G, node) nnbrs = nx.non_neighbors(G, node) c_1, i_1 = ramsey_R2(G.subgraph(nbrs)) diff --git a/networkx/algorithms/cluster.py b/networkx/algorithms/cluster.py index 8947b3cd..89c3254b 100644 --- a/networkx/algorithms/cluster.py +++ b/networkx/algorithms/cluster.py @@ -1,21 +1,28 @@ # -*- coding: utf-8 -*- +# +# Copyright (C) 2004-2015 by +# Aric Hagberg <hagberg@lanl.gov> +# Dan Schult <dschult@colgate.edu> +# Pieter Swart <swart@lanl.gov> +# All rights reserved. +# BSD license. """Algorithms to characterize the number of triangles in a graph.""" from itertools import combinations + import networkx as nx from networkx import NetworkXError +from ..utils import not_implemented_for + __author__ = """\n""".join(['Aric Hagberg <aric.hagberg@gmail.com>', 'Dan Schult (dschult@colgate.edu)', 'Pieter Swart (swart@lanl.gov)', 'Jordi Torrents <jtorrents@milnou.net>']) -# Copyright (C) 2004-2015 by -# Aric Hagberg <hagberg@lanl.gov> -# Dan Schult <dschult@colgate.edu> -# Pieter Swart <swart@lanl.gov> -# All rights reserved. -# BSD license. + __all__= ['triangles', 'average_clustering', 'clustering', 'transitivity', 'square_clustering'] + +@not_implemented_for('directed') def triangles(G, nodes=None): """Compute the number of triangles. @@ -49,12 +56,13 @@ def triangles(G, nodes=None): three times, once at each node. Self loops are ignored. """ - if G.is_directed(): - raise NetworkXError("triangles() is not defined for directed graphs.") + # If `nodes` represents a single node in the graph, return only its number + # of triangles. if nodes in G: - # return single value return next(_triangles_and_degree_iter(G,nodes))[2] // 2 - return dict( (v,t // 2) for v,d,t in _triangles_and_degree_iter(G,nodes)) + # Otherwise, `nodes` represents an iterable of nodes, so return a + # dictionary mapping node to number of triangles. + return {v: t // 2 for v, d, t in _triangles_and_degree_iter(G, nodes)} def _triangles_and_degree_iter(G,nodes=None): """ Return an iterator of (node, degree, triangles). diff --git a/networkx/algorithms/components/connected.py b/networkx/algorithms/components/connected.py index 45398538..7280b1b9 100644 --- a/networkx/algorithms/components/connected.py +++ b/networkx/algorithms/components/connected.py @@ -10,6 +10,7 @@ Connected components. # BSD license. import networkx as nx from networkx.utils.decorators import not_implemented_for +from ...utils import arbitrary_element __authors__ = "\n".join(['Eben Kenah', 'Aric Hagberg <aric.hagberg@gmail.com>' @@ -170,7 +171,7 @@ def is_connected(G): if len(G) == 0: raise nx.NetworkXPointlessConcept('Connectivity is undefined ', 'for the null graph.') - return len(set(_plain_bfs(G, next(G.nodes_iter())))) == len(G) + return len(set(_plain_bfs(G, arbitrary_element(G)))) == len(G) @not_implemented_for('directed') diff --git a/networkx/algorithms/connectivity/connectivity.py b/networkx/algorithms/connectivity/connectivity.py index 51fbfea3..a16e1f18 100644 --- a/networkx/algorithms/connectivity/connectivity.py +++ b/networkx/algorithms/connectivity/connectivity.py @@ -5,6 +5,7 @@ Flow based connectivity algorithms from __future__ import division import itertools +from operator import itemgetter import networkx as nx # Define the default maximum flow function to use in all flow based @@ -325,9 +326,7 @@ def node_connectivity(G, s=None, t=None, flow_func=None): kwargs = dict(flow_func=flow_func, auxiliary=H, residual=R) # Pick a node with minimum degree - degree = G.degree() - minimum_degree = min(degree.values()) - v = next(n for n, d in degree.items() if d == minimum_degree) + v, minimum_degree = min(G.degree().items(), key=itemgetter(1)) # Node connectivity is bounded by degree. K = minimum_degree # compute local node connectivity with all its non-neighbors nodes diff --git a/networkx/algorithms/connectivity/stoerwagner.py b/networkx/algorithms/connectivity/stoerwagner.py index 50498a39..28268904 100644 --- a/networkx/algorithms/connectivity/stoerwagner.py +++ b/networkx/algorithms/connectivity/stoerwagner.py @@ -1,16 +1,20 @@ # -*- coding: utf-8 -*- +# +# Copyright (C) 2014 +# ysitu <ysitu@users.noreply.github.com> +# All rights reserved. +# BSD license. """ Stoer-Wagner minimum cut algorithm. """ from itertools import islice + import networkx as nx -from networkx.utils import * +from ...utils import BinaryHeap +from ...utils import not_implemented_for +from ...utils import arbitrary_element __author__ = 'ysitu <ysitu@users.noreply.github.com>' -# Copyright (C) 2014 -# ysitu <ysitu@users.noreply.github.com> -# All rights reserved. -# BSD license. __all__ = ['stoer_wagner'] @@ -109,7 +113,7 @@ def stoer_wagner(G, weight='weight', heap=BinaryHeap): # Repeatedly pick a pair of nodes to contract until only one node is left. for i in range(n - 1): # Pick an arbitrary node u and create a set A = {u}. - u = next(iter(G)) + u = arbitrary_element(G) A = set([u]) # Repeatedly pick the node "most tightly connected" to A and add it to # A. The tightness of connectivity of a node not in A is defined by the diff --git a/networkx/algorithms/dag.py b/networkx/algorithms/dag.py index ac138f62..5666cc5c 100644 --- a/networkx/algorithms/dag.py +++ b/networkx/algorithms/dag.py @@ -1,7 +1,4 @@ # -*- coding: utf-8 -*- -from fractions import gcd -import networkx as nx -from networkx.utils.decorators import * """Algorithms for directed acyclic graphs (DAGs).""" # Copyright (C) 2006-2011 by # Aric Hagberg <hagberg@lanl.gov> @@ -9,6 +6,12 @@ from networkx.utils.decorators import * # Pieter Swart <swart@lanl.gov> # All rights reserved. # BSD license. +from fractions import gcd + +import networkx as nx +from networkx.utils.decorators import * +from ..utils import arbitrary_element + __author__ = """\n""".join(['Aric Hagberg <aric.hagberg@gmail.com>', 'Dan Schult (dschult@colgate.edu)', 'Ben Edwards (bedwards@cs.unm.edu)']) @@ -279,7 +282,7 @@ def is_aperiodic(G): raise nx.NetworkXError( "is_aperiodic not defined for undirected graphs") - s = next(G.nodes_iter()) + s = arbitrary_element(G) levels = {s: 0} this_level = [s] g = 0 diff --git a/networkx/algorithms/euler.py b/networkx/algorithms/euler.py index c65abfc4..afa99e41 100644 --- a/networkx/algorithms/euler.py +++ b/networkx/algorithms/euler.py @@ -1,20 +1,24 @@ # -*- coding: utf-8 -*- +# +# Copyright (C) 2010 by +# Aric Hagberg <hagberg@lanl.gov> +# Dan Schult <dschult@colgate.edu> +# Pieter Swart <swart@lanl.gov> +# All rights reserved. +# BSD license. """ Eulerian circuits and graphs. """ import networkx as nx +from ..utils import arbitrary_element + __author__ = """\n""".join(['Nima Mohammadi (nima.irt[AT]gmail.com)', 'Aric Hagberg <hagberg@lanl.gov>']) -# Copyright (C) 2010 by -# Aric Hagberg <hagberg@lanl.gov> -# Dan Schult <dschult@colgate.edu> -# Pieter Swart <swart@lanl.gov> -# All rights reserved. -# BSD license. __all__ = ['is_eulerian', 'eulerian_circuit'] + def is_eulerian(G): """Return True if G is an Eulerian graph, False otherwise. @@ -43,13 +47,13 @@ def is_eulerian(G): # Every node must have equal in degree and out degree for n in G.nodes_iter(): if G.in_degree(n) != G.out_degree(n): - return False + return False # Must be strongly connected if not nx.is_strongly_connected(G): return False else: # An undirected Eulerian graph has no vertices of odd degrees - for v,d in G.degree_iter(): + for v, d in G.degree_iter(): if d % 2 != 0: return False # Must be connected @@ -110,11 +114,11 @@ def eulerian_circuit(G, source=None): from operator import itemgetter if not is_eulerian(G): raise nx.NetworkXError("G is not Eulerian.") - g = G.__class__(G) # copy graph structure (not attributes) + g = G.__class__(G) # copy graph structure (not attributes) # set starting node if source is None: - v = next(g.nodes_iter()) + v = arbitrary_element(g) else: v = source @@ -137,6 +141,6 @@ def eulerian_circuit(G, source=None): last_vertex = current_vertex vertex_stack.pop() else: - random_edge = next(edges(current_vertex)) - vertex_stack.append(get_vertex(random_edge)) - g.remove_edge(*random_edge) + arbitrary_edge = next(edges(current_vertex)) + vertex_stack.append(get_vertex(arbitrary_edge)) + g.remove_edge(*arbitrary_edge) diff --git a/networkx/algorithms/flow/capacityscaling.py b/networkx/algorithms/flow/capacityscaling.py index 357dad76..3bf996d4 100644 --- a/networkx/algorithms/flow/capacityscaling.py +++ b/networkx/algorithms/flow/capacityscaling.py @@ -13,8 +13,10 @@ __all__ = ['capacity_scaling'] from itertools import chain from math import log import networkx as nx -from networkx.utils import * - +from ...utils import BinaryHeap +from ...utils import generate_unique_node +from ...utils import not_implemented_for +from ...utils import arbitrary_element def _detect_unboundedness(R): """Detect infinite-capacity negative cycles. @@ -308,7 +310,7 @@ def capacity_scaling(G, demand='demand', capacity='capacity', weight='weight', # Repeatedly augment flow from S to T along shortest paths until # Δ-feasibility is achieved. while S and T: - s = next(iter(S)) + s = arbitrary_element(S) t = None # Search for a shortest path in terms of reduce costs from s to # any t in T in the Δ-residual network. diff --git a/networkx/algorithms/flow/preflowpush.py b/networkx/algorithms/flow/preflowpush.py index 3db0ae09..6bb3e4a0 100644 --- a/networkx/algorithms/flow/preflowpush.py +++ b/networkx/algorithms/flow/preflowpush.py @@ -11,7 +11,13 @@ __author__ = """ysitu <ysitu@users.noreply.github.com>""" from collections import deque from itertools import islice import networkx as nx -from networkx.algorithms.flow.utils import * +#from networkx.algorithms.flow.utils import * +from ...utils import arbitrary_element +from .utils import build_residual_network +from .utils import CurrentEdge +from .utils import detect_unboundedness +from .utils import GlobalRelabelThreshold +from .utils import Level __all__ = ['preflow_push'] @@ -233,7 +239,7 @@ def preflow_push_impl(G, s, t, capacity, residual, global_relabel_freq, # Record the old height and level for the gap heuristic. old_height = height old_level = level - u = next(iter(level.active)) + u = arbitrary_element(level.active) height = discharge(u, True) if grt.is_reached(): # Global relabeling heuristic: Recompute the exact heights of @@ -277,7 +283,7 @@ def preflow_push_impl(G, s, t, capacity, residual, global_relabel_freq, # Move to the next lower level. height -= 1 break - u = next(iter(level.active)) + u = arbitrary_element(level.active) height = discharge(u, False) if grt.is_reached(): # Global relabeling heuristic. diff --git a/networkx/algorithms/minors.py b/networkx/algorithms/minors.py index f91c0be4..197e62d3 100644 --- a/networkx/algorithms/minors.py +++ b/networkx/algorithms/minors.py @@ -12,24 +12,12 @@ from itertools import combinations from itertools import permutations from itertools import product +from ..utils import arbitrary_element + __all__ = ['contracted_edge', 'contracted_nodes', 'identified_nodes', 'quotient_graph'] -def peek(iterable): - """Returns an arbitrary element of ``iterable`` without removing it. - - This is most useful for peeking at an arbitrary element of a set:: - - >>> peek({3, 2, 1}) - 1 - >>> peek('hello') - 'h' - - """ - return next(iter(iterable)) - - def equivalence_classes(iterable, relation): """Returns the set of equivalence classes of the given ``iterable`` under the specified equivalence relation. @@ -53,7 +41,7 @@ def equivalence_classes(iterable, relation): # # Each block is guaranteed to be non-empty for block in blocks: - x = peek(block) + x = arbitrary_element(block) if relation(x, y): block.append(y) break diff --git a/networkx/algorithms/tests/test_minors.py b/networkx/algorithms/tests/test_minors.py index 44ae7069..79a1411b 100644 --- a/networkx/algorithms/tests/test_minors.py +++ b/networkx/algorithms/tests/test_minors.py @@ -12,6 +12,7 @@ from nose.tools import assert_true from nose.tools import raises import networkx as nx +from networkx.utils import arbitrary_element class TestQuotient(object): @@ -57,8 +58,8 @@ class TestQuotient(object): """ G = nx.path_graph(5) identity = lambda u, v: u == v - peek = lambda x: next(iter(x)) - same_parity = lambda b, c: peek(b) % 2 == peek(c) % 2 + same_parity = lambda b, c: (arbitrary_element(b) % 2 + == arbitrary_element(c) % 2) actual = nx.quotient_graph(G, identity, same_parity) expected = nx.Graph() expected.add_edges_from([(0, 2), (0, 4), (2, 4)]) diff --git a/networkx/algorithms/tests/test_simple_paths.py b/networkx/algorithms/tests/test_simple_paths.py index 81531763..c068c70a 100644 --- a/networkx/algorithms/tests/test_simple_paths.py +++ b/networkx/algorithms/tests/test_simple_paths.py @@ -6,6 +6,7 @@ import networkx as nx from networkx import convert_node_labels_to_integers as cnlti from networkx.algorithms.simple_paths import _bidirectional_shortest_path from networkx.algorithms.simple_paths import _bidirectional_dijkstra +from networkx.utils import arbitrary_element # Tests for all_simple_paths def test_all_simple_paths(): @@ -44,7 +45,7 @@ def test_all_simple_paths_empty(): assert_equal(list(list(p) for p in paths),[]) def hamiltonian_path(G,source): - source = next(G.nodes_iter()) + source = arbitrary_element(G) neighbors = set(G[source])-set([source]) n = len(G) for target in neighbors: |
